ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-07-16 06:07:19
Exec Total Coverage
Lines: 4072 5061 80.5%
Functions: 279 320 87.2%
Branches: 3159 5107 61.9%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 410 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 410 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 575 void maps_init_game_vars()
67 {
68 575 viewport = {};
69 575 viewport_mode = ViewportMode::CenterAndBound;
70 575 viewport_sprite_uid = 1;
71 575 currscr_for_passive_subscr = -1;
72 575 }
73
74 static region_ids_t current_region_ids;
75
76 14621108 static bool is_a_region(int map, int scr)
77 {
78 14621108 return get_region_id(map, scr) != 0;
79 }
80
81 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
82 {
83
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_a_region(map, scr)) return false;
84 1460 int region_id = get_region_id(map, region_origin_scr);
85
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
86 2232 }
87
88 138234120 bool is_in_current_region(int map, int screen)
89 {
90
5/6
✓ Branch 0 taken 138232547 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 138232547 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12213 times.
✓ Branch 5 taken 138220334 times.
138234120 return map == cur_map && screen >= 0 && screen < 128 && screen_in_current_region[screen];
91 }
92
93 69622375 bool is_in_current_region(int screen)
94 {
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 69622374 times.
69622375 return screen < 128 && screen_in_current_region[screen];
96 }
97
98 29028180 bool is_in_current_region(mapscr* scr)
99 {
100
4/4
✓ Branch 0 taken 29013159 times.
✓ Branch 1 taken 15021 times.
✓ Branch 2 taken 462663 times.
✓ Branch 3 taken 28550496 times.
29028180 return scr->map == cur_map && scr->screen < 128 && screen_in_current_region[scr->screen];
101 }
102
103 bool is_in_scrolling_region(int screen)
104 {
105 if (!screenscrolling) return false;
106
107 int x = screen % 16;
108 int y = screen / 16;
109 return
110 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
111 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
112 }
113
114 9028294438 bool is_in_scrolling_region()
115 {
116 9028294438 return cur_region.screen_count > 1;
117 }
118
119 76853492 bool is_extended_height_mode()
120 {
121
2/2
✓ Branch 0 taken 76603358 times.
✓ Branch 1 taken 250134 times.
76853492 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
122 }
123
124 // Returns 0 if this is not a region.
125 15663158 int get_region_id(int map, int screen)
126 {
127
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 15261723 times.
15663158 if (screen >= 128) return 0;
128
2/2
✓ Branch 0 taken 15260623 times.
✓ Branch 1 taken 1100 times.
15261723 if (map == cur_region.map) return current_region_ids[screen];
129
130 1100 return Regions[map].get_region_id(screen);
131 15663158 }
132
133 982758 int get_current_region_id()
134 {
135 982758 return get_region_id(cur_map, cur_screen);
136 }
137
138 64226 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
139 {
140 64226 region.map = map;
141
142
3/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 63952 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 274 times.
64226 if (!(is_a_region(map, screen)) || screen >= 0x80)
143 {
144 63952 region.region_id = 0;
145 63952 region.origin_screen = screen;
146 63952 region.origin_screen_x = screen % 16;
147 63952 region.origin_screen_y = screen / 16;
148 63952 region.screen_width = 1;
149 63952 region.screen_height = 1;
150 63952 region.screen_count = 1;
151 63952 region.width = 256;
152 63952 region.height = 176;
153 63952 region_scr_dx = 0;
154 63952 region_scr_dy = 0;
155 63952 return;
156 }
157
158 274 int input_scr_x = screen % 16;
159 274 int input_scr_y = screen / 16;
160
161 // For the given screen, find the top-left corner of its region.
162 274 int origin_scr_x = input_scr_x;
163 274 int origin_scr_y = input_scr_y;
164 274 int origin_scr = screen;
165
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
166 {
167
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
168 160 origin_scr_x--;
169 }
170
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
171 {
172
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
173 234 origin_scr_y--;
174 }
175 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
176
177 // Now find the bottom-right corner.
178 274 int region_scr_right = origin_scr_x;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
180 {
181
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
182 368 region_scr_right++;
183 }
184 274 int region_scr_bottom = origin_scr_y;
185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
186 {
187
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
188 582 region_scr_bottom++;
189 }
190
191 274 region.region_id = get_region_id(map, origin_scr);
192 274 region.origin_screen = origin_scr;
193 274 region.origin_screen_x = origin_scr_x;
194 274 region.origin_screen_y = origin_scr_y;
195 274 region.screen_width = region_scr_right - origin_scr_x + 1;
196 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
197 274 region.screen_count = region.screen_width * region.screen_height;
198 274 region.width = 256 * region.screen_width;
199 274 region.height = 176 * region.screen_height;
200 274 region_scr_dx = input_scr_x - origin_scr_x;
201 274 region_scr_dy = input_scr_y - origin_scr_y;
202
203 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
204 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
205 64226 }
206
207 35860 void load_region(int dmap, int screen)
208 {
209 35860 clear_temporary_screens();
210
211 35860 int map = DMaps[dmap].map;
212 35860 current_region_ids = Regions[map].get_all_region_ids();
213
214 35860 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
215 35860 cur_screen = cur_region.origin_screen;
216 35860 world_w = cur_region.width;
217 35860 world_h = cur_region.height;
218 35860 region_scr_count = cur_region.screen_count;
219 35860 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
220 35860 region_num_rpos = cur_region.screen_count*176;
221 35860 scrolling_maze_last_solved_screen = 0;
222
223 35860 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
224
2/2
✓ Branch 0 taken 36094 times.
✓ Branch 1 taken 35860 times.
71954 for (int x = 0; x < cur_region.screen_width; x++)
225 {
226
2/2
✓ Branch 0 taken 37104 times.
✓ Branch 1 taken 36094 times.
73198 for (int y = 0; y < cur_region.screen_height; y++)
227 {
228 37104 int screen = cur_screen + x + y*16;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37104 times.
37104 if (screen < 136)
230 {
231 37104 screen_in_current_region[screen] = true;
232 37104 }
233 37104 }
234 36094 }
235
236 35860 mark_current_region_handles_dirty();
237 35860 }
238
239 35860 static void prepare_current_region_handles()
240 {
241 35860 current_region_rpos_handles_dirty = false;
242 35860 current_region_screen_count = 0;
243
2/2
✓ Branch 0 taken 36208 times.
✓ Branch 1 taken 35860 times.
72068 for (int y = 0; y < cur_region.screen_height; y++)
244 {
245
2/2
✓ Branch 0 taken 37104 times.
✓ Branch 1 taken 36208 times.
73312 for (int x = 0; x < cur_region.screen_width; x++)
246 {
247 37104 int screen = cur_screen + x + y*16;
248 37104 int index_start = current_region_screen_count;
249
2/2
✓ Branch 0 taken 37104 times.
✓ Branch 1 taken 259728 times.
296832 for (int layer = 0; layer <= 6; layer++)
250 {
251 259728 mapscr* scr = get_scr_layer(screen, layer);
252
2/2
✓ Branch 0 taken 84583 times.
✓ Branch 1 taken 175145 times.
259728 if (!scr->is_valid())
253 {
254
1/2
✓ Branch 0 taken 175145 times.
✗ Branch 1 not taken.
175145 if (layer == 0) break;
255 175145 continue;
256 }
257
258 84583 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
259 84583 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
260 84583 current_region_screen_count += 1;
261 84583 }
262
263 37104 int num_handles_for_scr = current_region_screen_count - index_start;
264 37104 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
265 37104 }
266 36208 }
267 35860 }
268
269 1783020838 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
270 {
271 DCHECK(!current_region_rpos_handles_dirty);
272 1783020838 return {current_region_rpos_handles, current_region_screen_count};
273 }
274
275 11071048 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
276 {
277 DCHECK(!current_region_rpos_handles_dirty);
278
2/4
✓ Branch 0 taken 11071048 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11071048 times.
11071048 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
279 return {nullptr, 0};
280
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11071048 times.
11071048 if (cur_screen >= 0x80)
282 {
283 DCHECK(scr == origin_scr);
284 return {nullptr, 0};
285 }
286
287 DCHECK(is_in_current_region(scr));
288 11071048 return current_region_rpos_handles_scr[scr->screen];
289 11071048 }
290
291 35860 void mark_current_region_handles_dirty()
292 {
293 35860 current_region_rpos_handles_dirty = true;
294 35860 }
295
296 36997 void clear_temporary_screens()
297 {
298
2/2
✓ Branch 0 taken 35221144 times.
✓ Branch 1 taken 36997 times.
35258141 for (int i = 0; i < 136*7; i++)
299 {
300
2/2
✓ Branch 0 taken 35166495 times.
✓ Branch 1 taken 54649 times.
35221144 if (temporary_screens[i])
301 {
302 54649 free(temporary_screens[i]);
303 54649 temporary_screens[i] = NULL;
304 54649 }
305 35221144 }
306
307 36997 origin_scr = nullptr;
308 36997 hero_scr = nullptr;
309 36997 }
310
311 27958 std::vector<mapscr*> take_temporary_scrs()
312 {
313
1/2
✓ Branch 0 taken 27958 times.
✗ Branch 1 not taken.
27958 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
314
2/2
✓ Branch 0 taken 27958 times.
✓ Branch 1 taken 26616016 times.
26643974 for (int i = 0; i < 136*7; i++)
315 26616016 temporary_screens[i] = nullptr;
316
317 27958 return screens;
318
1/2
✓ Branch 0 taken 27958 times.
✗ Branch 1 not taken.
27958 }
319
320 14555010 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
321 {
322 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
323
324
2/2
✓ Branch 0 taken 14508428 times.
✓ Branch 1 taken 46582 times.
14555010 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
325 14555010 viewport.w = 256;
326 14555010 viewport.h = 176 + (extended_height_mode ? 56 : 0);
327
328
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14554650 times.
14555010 if (viewport_mode == ViewportMode::Script)
329 360 return;
330
331
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14508488 times.
14554650 if (!is_a_region(DMaps[dmap].map, screen))
332 {
333 14508488 viewport.x = 0;
334 14508488 viewport.y = 0;
335 14508488 }
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
337 {
338 // Clamp the viewport to the edges of the region.
339
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
340
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
341 46162 }
342 else if (viewport_mode == ViewportMode::Center)
343 {
344 viewport.x = x - viewport.w/2;
345 viewport.y = y - viewport.h/2;
346 }
347 14555010 }
348
349 14554499 sprite* get_viewport_sprite()
350 {
351 14554499 sprite* spr = sprite::getByUID(viewport_sprite_uid);
352
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14554493 times.
14554499 if (!spr)
353 {
354 6 viewport_sprite_uid = 1; // Hero uid.
355 6 spr = &Hero;
356 6 }
357
358 14554499 return spr;
359 }
360
361 6 void set_viewport_sprite(sprite* spr)
362 {
363 6 viewport_sprite_uid = spr->uid;
364 6 }
365
366 14526541 void update_viewport()
367 {
368 14526541 sprite* spr = get_viewport_sprite();
369 14526541 int x = spr->x + spr->txsz*16/2;
370 14526541 int y = spr->y + spr->tysz*16/2;
371 14526541 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
372 14526541 }
373
374 14314346 void update_heroscr()
375 {
376 void playLevelMusic();
377
378 14314346 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
379 14314346 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
380 14314346 int dx = x / 256;
381 14314346 int dy = y / 176;
382 14314346 int new_screen = cur_screen + dx + dy * 16;
383
2/2
✓ Branch 0 taken 14306584 times.
✓ Branch 1 taken 7762 times.
14314346 if (maze_state.active == 1)
384 7762 new_screen = maze_state.scr->screen;
385
7/12
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 14314130 times.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 216 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 216 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 216 times.
14314346 if (hero_screen != new_screen && dx >= 0 && dy >= 0 && dx < 16 && dy < 8 && is_in_current_region(new_screen))
386 {
387 216 region_scr_dx = dx;
388 216 region_scr_dy = dy;
389 216 hero_screen = new_screen;
390 216 prev_hero_scr = hero_scr;
391 216 hero_scr = get_scr(hero_screen);
392 216 Hero.screen_spawned = hero_screen;
393 216 playLevelMusic();
394 216 }
395
1/2
✓ Branch 0 taken 14314346 times.
✗ Branch 1 not taken.
14314346 if (game->get_regionmapping() == REGION_MAPPING_PHYSICAL)
396 mark_visited(new_screen); // Mark each screen the hero steps foot in as visited
397 14314346 }
398
399 4722 mapscr* determine_hero_screen_from_coords()
400 {
401 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
402 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
403 4722 int dx = x / 256;
404 4722 int dy = y / 176;
405 4722 return get_scr(cur_screen + dx + dy * 16);
406 }
407
408 26928 bool edge_of_region(direction dir)
409 {
410
2/2
✓ Branch 0 taken 26848 times.
✓ Branch 1 taken 80 times.
26928 if (!is_in_scrolling_region()) return true;
411
412 80 int screen_x = hero_screen % 16;
413 80 int screen_y = hero_screen / 16;
414
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
415
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
416
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
417
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
418
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
419 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
420 26928 }
421
422 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
423 // Coordinates are clamped to the world bounds.
424 212172024 int get_screen_for_world_xy(int x, int y)
425 {
426
2/2
✓ Branch 0 taken 189382412 times.
✓ Branch 1 taken 22789612 times.
212172024 if (!is_in_scrolling_region())
427 189382412 return cur_screen;
428
429 22789612 int dx = std::clamp(x, 0, world_w - 1) / 256;
430 22789612 int dy = std::clamp(y, 0, world_h - 1) / 176;
431 22789612 int origin_screen_x = cur_screen % 16;
432 22789612 int origin_screen_y = cur_screen / 16;
433 22789612 int scr_x = origin_screen_x + dx;
434 22789612 int scr_y = origin_screen_y + dy;
435 22789612 return map_scr_xy_to_index(scr_x, scr_y);
436 212172024 }
437
438 32518504 int get_screen_for_rpos(rpos_t rpos)
439 {
440 32518504 int origin_screen_x = cur_screen % 16;
441 32518504 int origin_screen_y = cur_screen / 16;
442 32518504 int screen = static_cast<int32_t>(rpos) / 176;
443 32518504 int scr_x = origin_screen_x + screen%cur_region.screen_width;
444 32518504 int scr_y = origin_screen_y + screen/cur_region.screen_width;
445 32518504 return map_scr_xy_to_index(scr_x, scr_y);
446 }
447
448 774804537 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
449 {
450 DCHECK_LAYER_ZERO_INDEX(layer);
451
2/2
✓ Branch 0 taken 742423993 times.
✓ Branch 1 taken 32380544 times.
774804537 if (!is_in_scrolling_region())
452 742423993 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
453 32380544 int screen = get_screen_for_rpos(rpos);
454 32380544 mapscr* scr = get_scr_layer(screen, layer);
455 32380544 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
456 774804537 }
457
458 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
459 // Coordinates are clamped to the world bounds.
460 3503661654 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
461 {
462 3503661654 x = std::clamp(x, 0, world_w - 1);
463 3503661654 y = std::clamp(y, 0, world_h - 1);
464
465 DCHECK_LAYER_ZERO_INDEX(layer);
466
2/2
✓ Branch 0 taken 3475924482 times.
✓ Branch 1 taken 27737172 times.
3503661654 if (!is_in_scrolling_region())
467 {
468 3475924482 int pos = COMBOPOS(x, y);
469 3475924482 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
470 }
471 27737172 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
472 3503661654 }
473
474 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
475 44 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
476 {
477 DCHECK_LAYER_ZERO_INDEX(layer);
478 44 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
479 }
480
481 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
482 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
483 62245 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
484 {
485 DCHECK_LAYER_ZERO_INDEX(layer);
486 62245 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
487 }
488
489 25183501 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
490 {
491 DCHECK_LAYER_ZERO_INDEX(layer);
492 25183501 rpos_handle.layer = layer;
493 25183501 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
494 25183501 }
495
496 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
497 // Coordinates are clamped to the world bounds.
498 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
499 {
500 DCHECK_LAYER_ZERO_INDEX(layer);
501
502 52808 x = std::clamp(x, 0, world_w - 1);
503 52808 y = std::clamp(y, 0, world_h - 1);
504
505 52808 auto maybe_ffc_handle = getFFCAt(x, y);
506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
507 return maybe_ffc_handle.value();
508
509 52808 auto rpos = COMBOPOS_REGION_B(x, y);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
511 return rpos_handle_t();
512 52808 return get_rpos_handle(rpos, layer);
513 52808 }
514
515 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
516 // directly or via zscript) only last until the next area is loaded (via loadscr).
517
518 // Returns the screen containing the (x, y) world position.
519 1634080438 mapscr* get_scr_for_world_xy(int x, int y)
520 {
521 // Quick path, but should work the same without.
522
2/2
✓ Branch 0 taken 1622947438 times.
✓ Branch 1 taken 11133000 times.
1634080438 if (!is_in_scrolling_region()) return origin_scr;
523 11133000 return get_scr(get_screen_for_world_xy(x, y));
524 1634080438 }
525
526 24525436 mapscr* get_scr_for_rpos(rpos_t rpos)
527 {
528 // Quick path, but should work the same without.
529
2/2
✓ Branch 0 taken 24387490 times.
✓ Branch 1 taken 137946 times.
24525436 if (!is_in_scrolling_region()) return origin_scr;
530 137946 return get_scr(get_screen_for_rpos(rpos));
531 24525436 }
532
533 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
534 {
535 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
536 }
537
538 // Note: layer=0 is the base screen, 1 is the first layer, etc.
539 2308869018 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
540 {
541 DCHECK_LAYER_ZERO_INDEX(layer);
542
2/2
✓ Branch 0 taken 2297449020 times.
✓ Branch 1 taken 11419998 times.
2308869018 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
543
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 10711064 times.
11419998 return layer == 0 ?
544 708934 get_scr_for_world_xy(x, y) :
545 10711064 get_scr_layer(get_screen_for_world_xy(x, y), layer);
546 2308869018 }
547
548 1834203798 int get_region_screen_offset(int screen)
549 {
550 1834203798 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
551 }
552
553 654673804 int get_screen_for_region_index_offset(int offset)
554 {
555 654673804 int scr_dx = offset % cur_region.screen_width;
556 654673804 int scr_dy = offset / cur_region.screen_width;
557 654673804 int screen = cur_screen + scr_dx + scr_dy*16;
558 654673804 return screen;
559 }
560
561 654489967 mapscr* get_scr_for_region_index_offset(int offset)
562 {
563 654489967 int screen = get_screen_for_region_index_offset(offset);
564 654489967 return get_scr(screen);
565 }
566
567 // The screen at (map, screen) must exist.
568 1422022453 mapscr* get_scr(int map, int screen)
569 {
570 1422022453 mapscr* scr = get_scr_maybe(map, screen);
571
1/2
✓ Branch 0 taken 1422022453 times.
✗ Branch 1 not taken.
1422022453 CHECK(scr);
572 1422022453 return scr;
573 }
574
575 837453657 mapscr* get_scr(int screen)
576 {
577 837453657 return get_scr(cur_map, screen);
578 }
579
580 // Returns null if active screen does not exist.
581 1451567431 mapscr* get_scr_maybe(int map, int screen)
582 {
583 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
584
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1451567431 times.
1451567431 if (map == cur_map)
586 {
587
2/2
✓ Branch 0 taken 1430792499 times.
✓ Branch 1 taken 20774932 times.
1451567431 if (screen == cur_screen)
588 1430792499 return origin_scr;
589
590 20774932 int index = screen*7;
591
2/2
✓ Branch 0 taken 20763842 times.
✓ Branch 1 taken 11090 times.
20774932 if (temporary_screens[index])
592 20763842 return temporary_screens[index];
593
594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (screen == home_screen)
595 return special_warp_return_scr;
596 11090 }
597
598
3/6
✓ Branch 0 taken 11090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
11090 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
599 {
600 11090 int index = screen*7;
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
602 11090 return FFCore.ScrollingScreensAll[index];
603 }
604
605 return nullptr;
606 1451567431 }
607
608 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
609 7065644524 mapscr* get_scr_layer(int map, int screen, int layer)
610 {
611 DCHECK_LAYER_ZERO_INDEX(layer);
612
2/2
✓ Branch 0 taken 6483564789 times.
✓ Branch 1 taken 582079735 times.
7065644524 if (layer == 0)
613 582079735 return get_scr(map, screen);
614
615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6483564789 times.
6483564789 if (map == cur_map)
616 {
617 6483564789 int index = screen*7 + layer;
618
2/2
✓ Branch 0 taken 6483496389 times.
✓ Branch 1 taken 68400 times.
6483564789 if (temporary_screens[index])
619 6483496389 return temporary_screens[index];
620
621
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
622 1860 return &special_warp_return_scrs[layer];
623 66540 }
624
625
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
626 {
627 66540 int index = screen*7 + layer;
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
629 66540 return FFCore.ScrollingScreensAll[index];
630 }
631
632 NOTREACHED();
633 7065644524 }
634
635 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
636 6666399932 mapscr* get_scr_layer(int screen, int layer)
637 {
638 6666399932 return get_scr_layer(cur_map, screen, layer);
639 }
640
641 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
642 // Return nullptr if screen is not valid.
643 397170765 mapscr* get_scr_layer_valid(int screen, int layer)
644 {
645
2/2
✓ Branch 0 taken 78282287 times.
✓ Branch 1 taken 318888478 times.
397170765 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
646 78282287 return scr;
647 318888478 return nullptr;
648 397170765 }
649
650 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
651 {
652 401 int x = get_region_relative_dx(screen);
653 401 int y = get_region_relative_dy(screen);
654
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
655 71 return nullptr;
656
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
657 return nullptr;
658
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
659 return nullptr;
660
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
661 189 return nullptr;
662
663 141 screen = screen_index_direction(screen, dir);
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
665 return get_scr(screen);
666
667 141 return nullptr;
668 401 }
669
670 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
671 {
672 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
673 183837 uint8_t i = id % MAXFFCS;
674 183837 mapscr* scr = get_scr(screen);
675 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
676 183837 return {scr, screen, id, i, ffc};
677 }
678
679 34566 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
680 {
681 34566 x += get_region_relative_dx(screen) * 256;
682 34566 y += get_region_relative_dy(screen) * 176;
683 34566 return {x, y};
684 }
685
686 1049517 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
687 {
688 1049517 int x = get_region_relative_dx(screen) * 256;
689 1049517 int y = get_region_relative_dy(screen) * 176;
690 1049517 return {x, y};
691 }
692
693 12145632760 int32_t COMBOPOS(int32_t x, int32_t y)
694 {
695 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
696 12145632760 return (y & 0xF0) + (x >> 4);
697 }
698 int32_t COMBOPOS_B(int32_t x, int32_t y)
699 {
700 if(unsigned(x) >= 256 || unsigned(y) >= 176)
701 return -1;
702 return (y & 0xF0) + (x >> 4);
703 }
704 3337315894 int32_t COMBOX(int32_t pos)
705 {
706 3337315894 return pos % 16 * 16;
707 }
708 3337315894 int32_t COMBOY(int32_t pos)
709 {
710 3337315894 return pos & 0xF0;
711 }
712
713 112672627 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
714 {
715
2/2
✓ Branch 0 taken 84119981 times.
✓ Branch 1 taken 28552646 times.
112672627 if (!is_in_scrolling_region())
716 84119981 return (rpos_t) COMBOPOS(x, y);
717
718 DCHECK(is_in_world_bounds(x, y));
719 28552646 int scr_dx = x / (16*16);
720 28552646 int scr_dy = y / (11*16);
721 28552646 int pos = COMBOPOS(x%256, y%176);
722 28552646 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
723 112672627 }
724 6308391448 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
725 {
726
2/2
✓ Branch 0 taken 1397883 times.
✓ Branch 1 taken 6306993565 times.
6308391448 if (!is_in_world_bounds(x, y))
727 1397883 return rpos_t::None;
728
729 6306993565 int scr_dx = x / (16*16);
730 6306993565 int scr_dy = y / (11*16);
731 6306993565 int pos = COMBOPOS(x%256, y%176);
732 6306993565 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 6308391448 }
734 25306934 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
735 {
736 25306934 int scr_index = static_cast<int32_t>(rpos) / 176;
737 25306934 int scr_dx = scr_index % cur_region.screen_width;
738 25306934 int scr_dy = scr_index / cur_region.screen_width;
739 25306934 int pos = RPOS_TO_POS(rpos);
740 25306934 int x = scr_dx*16*16 + COMBOX(pos);
741 25306934 int y = scr_dy*11*16 + COMBOY(pos);
742 25306934 return {x, y};
743 }
744 60396 int32_t COMBOX_REGION(rpos_t rpos)
745 {
746 60396 auto [x, y] = COMBOXY_REGION(rpos);
747 60396 return x;
748 }
749 12225 int32_t COMBOY_REGION(rpos_t rpos)
750 {
751 12225 auto [x, y] = COMBOXY_REGION(rpos);
752 12225 return y;
753 }
754
755 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
756 {
757 DCHECK(is_in_world_bounds(x, y));
758
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
759 70177 return (rpos_t)(x + y * 16);
760
761 int scr_dx = x / 16;
762 int scr_dy = y / 11;
763 x %= 16;
764 y %= 11;
765 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
766 70177 }
767 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
768 {
769 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
770 70632 int scr_dx = scr_index % cur_region.screen_width;
771 70632 int scr_dy = scr_index / cur_region.screen_width;
772 70632 int pos = RPOS_TO_POS(rpos);
773 70632 int x = scr_dx*16 + pos%16;
774 70632 int y = scr_dy*11 + pos/16;
775 70632 return {x, y};
776 }
777
778 82541612 int32_t mapind(int32_t map, int32_t scr)
779 {
780 82541612 return map * MAPSCRSNORMAL + scr;
781 }
782
783 FONT *get_zc_font(int index);
784
785 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
786 extern movingblock mblock2; //mblock[4]?
787 extern portal mirror_portal;
788
789 void Z_message_d(const char *format,...)
790 {
791 #ifdef _DEBUG
792 char buf[512];
793 va_list ap;
794 va_start(ap, format);
795 vsprintf(buf, format, ap);
796 va_end(ap);
797
798 al_trace("%s",buf);
799 #else
800 format=format;
801 #endif
802 }
803
804
805
806 bool checktrigger=false;
807
808 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
809 {
810 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
811 int32_t index = script_drawing_commands.GetNext();
812
813 if(index < 0)
814 return;
815
816 int32_t *sdci = &script_drawing_commands[index][0];
817
818 sdci[0] = RECTR;
819 sdci[1] = 30000;
820 sdci[2] = x1*10000;
821 sdci[3] = y1*10000;
822 sdci[4] = x2*10000;
823 sdci[5] = y2*10000;
824 sdci[6] = 10000;
825 sdci[7] = 10000;
826 sdci[8] = 0;
827 sdci[9] = 0;
828 sdci[10] = 0;
829 sdci[11] = 10000;
830 sdci[12] = 1280000;
831 }
832
833 void clear_dmap(word i)
834 {
835 DMaps[i].clear();
836 }
837
838 void clear_dmaps()
839 {
840 for(int32_t i=0; i<MAXDMAPS; i++)
841 {
842 clear_dmap(i);
843 }
844 }
845
846 223687010 int32_t isdungeon(int32_t dmap, int32_t screen)
847 {
848
2/2
✓ Branch 0 taken 223641330 times.
✓ Branch 1 taken 45680 times.
223687010 if (dmap < 0) dmap = cur_dmap;
849
850 // dungeons can have any dlevel above 0
851
2/2
✓ Branch 0 taken 122437565 times.
✓ Branch 1 taken 101249445 times.
223687010 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
852 {
853
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
854 9961 return 0;
855
856 101239484 return 1;
857 }
858
859 // dlevels that aren't dungeons are caves
860
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122400738 times.
122437565 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
861 36827 return 1;
862
863 122400738 return 0;
864 223687010 }
865
866 39954817 int32_t isdungeon(int32_t screen)
867 {
868 39954817 return isdungeon(cur_dmap, screen);
869 }
870
871 183605244 int32_t isdungeon()
872 {
873 183605244 return isdungeon(cur_dmap, hero_screen);
874 }
875
876 88938 bool canPermSecret(int32_t dmap, int32_t screen)
877 {
878
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 75028 times.
88938 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
879 }
880
881 1375873881 int32_t MAPCOMBO(int32_t x, int32_t y)
882 {
883 1375873881 x = vbound(x, 0, world_w-1);
884 1375873881 y = vbound(y, 0, world_h-1);
885 1375873881 int pos = COMBOPOS(x%256, y%176);
886 1375873881 mapscr* scr = get_scr_for_world_xy(x, y);
887 1375873881 return scr->data[pos];
888 }
889
890 //specific layers 1 to 6
891 1709474483 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
892 {
893 DCHECK(layer >= 1 && layer <= 6);
894
3/4
✓ Branch 0 taken 1689116501 times.
✓ Branch 1 taken 20357982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1689116501 times.
1709474483 if (!is_in_world_bounds(x, y) || layer <= 0)
895 20357982 return 0;
896
897 1689116501 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
898
2/2
✓ Branch 0 taken 497140626 times.
✓ Branch 1 taken 1191975875 times.
1689116501 if (!m->is_valid())
899 1191975875 return 0;
900
901 497140626 int pos = COMBOPOS(x%256, y%176);
902 497140626 return m->data[pos];
903 1709474483 }
904
905 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
906 {
907 DCHECK(layer >= 1 && layer <= 6);
908 if (!is_in_world_bounds(x, y) || layer <= 0)
909 return 0;
910
911 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
912 if (!m->is_valid())
913 return 0;
914
915 int pos = COMBOPOS(x%256, y%176);
916 return m->cset[pos];
917 }
918
919 189244 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
920 {
921 DCHECK(layer >= 1 && layer <= 6);
922
2/4
✓ Branch 0 taken 189244 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189244 times.
189244 if (!is_in_world_bounds(x, y) || layer <= 0)
923 return 0;
924
925 189244 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
926
2/2
✓ Branch 0 taken 148850 times.
✓ Branch 1 taken 40394 times.
189244 if (!m->is_valid())
927 40394 return 0;
928
929 148850 int pos = COMBOPOS(x%256, y%176);
930 148850 return m->sflag[pos];
931 189244 }
932
933 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
934 {
935 DCHECK(layer >= 1 && layer <= 6);
936
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
937 return 0;
938
939 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
940
2/2
✓ Branch 0 taken 5809 times.
✓ Branch 1 taken 472 times.
6281 if (!m->is_valid())
941 472 return 0;
942
943 5809 int pos = COMBOPOS(x%256, y%176);
944 5809 return combobuf[m->data[pos]].type;
945 6281 }
946
947 189244 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
948 {
949 DCHECK(layer >= 1 && layer <= 6);
950
2/4
✓ Branch 0 taken 189244 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189244 times.
189244 if (!is_in_world_bounds(x, y) || layer <= 0)
951 return 0;
952
953 189244 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
954
2/2
✓ Branch 0 taken 148850 times.
✓ Branch 1 taken 40394 times.
189244 if (!m->is_valid())
955 40394 return 0;
956
957 148850 int pos = COMBOPOS(x%256, y%176);
958 148850 return combobuf[m->data[pos]].flag;
959 189244 }
960
961
962 // True if the FFC covers x, y and is not ethereal or a changer.
963 2467380355 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
964 {
965
2/2
✓ Branch 0 taken 746716410 times.
✓ Branch 1 taken 1720663945 times.
2467380355 if (ffc_handle.data()<=0)
966 746716410 return false;
967
968
2/2
✓ Branch 0 taken 300884516 times.
✓ Branch 1 taken 1419779429 times.
1720663945 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
969 300884516 return false;
970
971 1419779429 int32_t fx=ffc_handle.ffc->x.getInt();
972
4/4
✓ Branch 0 taken 976247210 times.
✓ Branch 1 taken 443532219 times.
✓ Branch 2 taken 866127455 times.
✓ Branch 3 taken 110119755 times.
1419779429 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
973 1309659674 return false;
974
975 110119755 int32_t fy=ffc_handle.ffc->y.getInt();
976
4/4
✓ Branch 0 taken 80138624 times.
✓ Branch 1 taken 29981131 times.
✓ Branch 2 taken 60071966 times.
✓ Branch 3 taken 20066658 times.
110119755 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
977 90053097 return false;
978
979 20066658 return true;
980 2467380355 }
981
982 998995209 int32_t MAPFFCOMBO(int32_t x,int32_t y)
983 {
984
2/2
✓ Branch 0 taken 13162521 times.
✓ Branch 1 taken 985832688 times.
998995209 if (auto ffc_handle = getFFCAt(x, y))
985 13162521 return ffc_handle->data();
986 985832688 return 0;
987 998995209 }
988
989 207232 int32_t MAPCSET(int32_t x, int32_t y)
990 {
991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
992 return 0;
993 207232 mapscr* scr = get_scr_for_world_xy(x, y);
994 207232 int pos = COMBOPOS(x%256, y%176);
995 207232 return scr->cset[pos];
996 207232 }
997
998 73668830 int32_t MAPFLAG(int32_t x, int32_t y)
999 {
1000
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73640690 times.
73668830 if (!is_in_world_bounds(x, y))
1001 28140 return 0;
1002 73640690 mapscr* scr = get_scr_for_world_xy(x, y);
1003 73640690 int pos = COMBOPOS(x%256, y%176);
1004 73640690 return scr->sflag[pos];
1005 73668830 }
1006
1007 165703913 int32_t COMBOTYPE(int32_t x,int32_t y)
1008 {
1009 165703913 int32_t b=1;
1010
2/2
✓ Branch 0 taken 96763544 times.
✓ Branch 1 taken 68940369 times.
165703913 if(x&8) b<<=2;
1011
2/2
✓ Branch 0 taken 83463769 times.
✓ Branch 1 taken 82240144 times.
165703913 if(y&8) b<<=1;
1012
1013
2/2
✓ Branch 0 taken 331400788 times.
✓ Branch 1 taken 165694835 times.
497095623 for (int32_t i = 0; i <= 1; ++i)
1014 {
1015
2/2
✓ Branch 0 taken 320242340 times.
✓ Branch 1 taken 11158448 times.
331400788 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1016 {
1017
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 320242340 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
320242340 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1018 320242340 }
1019 else
1020 {
1021
4/4
✓ Branch 0 taken 12230 times.
✓ Branch 1 taken 11146218 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 9078 times.
11158448 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1022 }
1023 331391710 }
1024
1025 165694835 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1026
5/6
✓ Branch 0 taken 3652838 times.
✓ Branch 1 taken 162041997 times.
✓ Branch 2 taken 3069902 times.
✓ Branch 3 taken 582936 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3069902 times.
165694835 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1027 {
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3069902 times.
3069902 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3069902 times.
3069902 if(cmb.usrflags&cflag3) return cNONE;
1030 3069902 }
1031 165694835 return cmb.type;
1032 165703913 }
1033
1034 50226821 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1035 {
1036 50226821 return combobuf[MAPFFCOMBO(x,y)].type;
1037 }
1038
1039 4971432 int32_t FFORCOMBO(int32_t x, int32_t y)
1040 {
1041
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4912916 times.
4971432 if (auto ffc_handle = getFFCAt(x, y))
1042 58516 return ffc_handle->data();
1043
1044 4912916 return MAPCOMBO(x,y);
1045 4971432 }
1046
1047 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1048 {
1049 for (int32_t i = 0; i <= 1; ++i)
1050 {
1051 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1052 {
1053 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1054 }
1055 else
1056 {
1057 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1058 }
1059 }
1060 int32_t b=1;
1061
1062 if(x&8) b<<=2;
1063
1064 if(y&8) b<<=1;
1065 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1066 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1067 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1068 return cmb.type;
1069 }
1070
1071 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1072 {
1073 if (auto ffc_handle = getFFCAt(x, y))
1074 return ffc_handle->data();
1075
1076 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1077 }
1078
1079 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1080 {
1081 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1082 }
1083
1084 70158055 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1085 {
1086
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 70130203 times.
70158055 if (!is_in_world_bounds(x, y))
1087 27852 return 0;
1088
1089 70130203 mapscr* scr = get_scr_for_world_xy(x, y);
1090 70130203 int pos = COMBOPOS(x%256, y%176);
1091 70130203 return combobuf[scr->data[pos]].flag;
1092 70158055 }
1093
1094 56844090 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1095 {
1096
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 56097913 times.
56844090 if (auto ffc_handle = getFFCAt(x, y))
1097 746177 return ffc_handle->cflag();
1098
1099 56097913 return 0;
1100 56844090 }
1101
1102 1313142741 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1103 {
1104 2788804008 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1105 1475661267 return ffcIsAt(ffc_handle, x, y);
1106 });
1107 }
1108
1109 3044 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1110 {
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3044 times.
3044 if (!rpos_handle.scr->is_valid()) return 0;
1112 3044 return rpos_handle.data();
1113 3044 }
1114
1115 3170105866 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1116 {
1117 DCHECK_LAYER_NEG1_INDEX(layer);
1118
2/2
✓ Branch 0 taken 22427070 times.
✓ Branch 1 taken 3147678796 times.
3170105866 if (!is_in_world_bounds(x, y)) return 0;
1119
2/2
✓ Branch 0 taken 3078461593 times.
✓ Branch 1 taken 69217203 times.
3147678796 if (layer == -1) return MAPCOMBO(x, y);
1120
1121 3078461593 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1122
2/2
✓ Branch 0 taken 2118699459 times.
✓ Branch 1 taken 959762134 times.
3078461593 if (!rpos_handle.scr->is_valid()) return 0;
1123
1124 959762134 return rpos_handle.data();
1125 3170105866 }
1126
1127 17375392 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1128 {
1129 17375392 auto cid = handle.data();
1130 17375392 auto* cmb = &handle.combo();
1131 17375392 bool done = false;
1132 17375392 std::set<int32_t> visited;
1133
2/2
✓ Branch 0 taken 17375392 times.
✓ Branch 1 taken 17375413 times.
34750805 while(!done)
1134 {
1135
2/4
✓ Branch 0 taken 17375413 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17375413 times.
17375413 if(visited.contains(cid))
1136 {
1137 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1138 break; // prevent infinite loop
1139 }
1140
1/2
✓ Branch 0 taken 17375413 times.
✗ Branch 1 not taken.
17375413 visited.insert(cid);
1141
1142 17375413 done = true; // don't loop again unless something changes
1143
2/2
✓ Branch 0 taken 17375392 times.
✓ Branch 1 taken 592658 times.
17968050 for(size_t idx = 0; idx < cmb->triggers.size(); ++idx)
1144 {
1145 592658 auto& trig = cmb->triggers[idx];
1146
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 592586 times.
592658 if (trig.triggerflags[4] & combotriggerSCREENLOAD)
1147
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 do_trigger_combo(handle, idx);
1148 592586 else continue; // can skip checking handle.data()
1149
1150
3/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 51 times.
72 if(handle.data() != cid)
1151 {
1152
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 cid = handle.data();
1153
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 cmb = &handle.combo();
1154 21 done = false; // loop again for the new combo
1155 21 break;
1156 }
1157 51 }
1158 }
1159 17375392 }
1160 51767 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1161 {
1162 51767 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1163 51767 }
1164 34819 void handle_region_load_trigger()
1165 {
1166
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 34667 times.
34819 if (is_in_scrolling_region())
1167 {
1168
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1169 {
1170
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1171 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1172 19456 }
1173 152 }
1174 34667 else handle_screen_load_trigger(create_screen_handles_one(get_scr(hero_screen)));
1175 34819 }
1176
1177 15800 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1178 {
1179 15800 auto screen_handles = create_screen_handles_one(&scr);
1180
1181
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 15261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15800 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1182 {
1183 539 reveal_hidden_stairs(&scr, screen, false);
1184 539 bool do_layers = false;
1185 539 bool from_active_screen = false;
1186 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1187 539 }
1188
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if (flags & mLIGHTBEAM)
1189 {
1190 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1191 if (rpos_handle.ctype() == cLIGHTTARGET)
1192 {
1193 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1194 rpos_handle.increment_data();
1195 }
1196 });
1197 }
1198
1199 15800 int lvl = DMaps[cur_dmap].level;
1200 15800 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1201 15800 toggle_gswitches_load(screen_handles);
1202
1203
2/2
✓ Branch 0 taken 15708 times.
✓ Branch 1 taken 92 times.
15800 if(flags&mLOCKBLOCK) // if special stuff done before
1204 {
1205 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1206 92 }
1207
1208
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1209 {
1210 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1211 }
1212
1213
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1214 {
1215 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1216 }
1217
1218
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1219 {
1220 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1221 }
1222
1223
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSCHEST) // if special stuff done before
1224 {
1225 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1226 }
1227
1228
1229 15800 int mi = mapind(map, screen);
1230 15800 clear_xdoors_mi(screen_handles, mi);
1231 15800 clear_xstatecombos_mi(screen_handles, mi);
1232
1233 15800 handle_screen_load_trigger(screen_handles);
1234 15800 }
1235
1236 53194 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1237 {
1238
2/4
✓ Branch 0 taken 53194 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53194 times.
53194 if (map < 0 || screen < 0)
1239 return std::nullopt;
1240
1241 53194 const mapscr* source = get_canonical_scr(map, screen);
1242
2/2
✓ Branch 0 taken 40960 times.
✓ Branch 1 taken 12234 times.
53194 if (!source->is_valid())
1243 12234 return std::nullopt;
1244
1245
2/2
✓ Branch 0 taken 8308 times.
✓ Branch 1 taken 32652 times.
40960 if (layer >= 0)
1246 {
1247
2/2
✓ Branch 0 taken 25160 times.
✓ Branch 1 taken 7492 times.
32652 if (source->layermap[layer] <= 0)
1248 25160 return std::nullopt;
1249
1250 7492 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1251
1/2
✓ Branch 0 taken 7492 times.
✗ Branch 1 not taken.
7492 if (!source->is_valid())
1252 return std::nullopt;
1253 7492 }
1254
1255
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1256 15800 mapscr scr = *source;
1257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15800 times.
15800 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1258
1259 15800 return scr;
1260 53194 }
1261
1262 27203 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1263 {
1264
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if (map < 0 || screen < 0) return 0;
1265
1266
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if(pos>175 || pos < 0)
1267 return 0;
1268
1269 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1270 // `apply_state_changes_to_screen` checks).
1271
4/5
✓ Branch 0 taken 4976 times.
✓ Branch 1 taken 22227 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4976 times.
✓ Branch 4 taken 22227 times.
32179 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1272 4976 return s->data[pos];
1273
1274 22227 return 0;
1275 27203 }
1276
1277 // Read from the current temporary screens or, if (map, screen) is not loaded,
1278 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1279 138223152 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1280 {
1281 DCHECK_LAYER_NEG1_INDEX(layer);
1282 DCHECK(map >= 0 && screen >= 0);
1283
1284
2/2
✓ Branch 0 taken 138195949 times.
✓ Branch 1 taken 27203 times.
138223152 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1285
1286 // Screen is not in the current region, so we have to load and trigger some secrets.
1287 27203 int pos = COMBOPOS(x, y);
1288 27203 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1289 138223152 }
1290
1291 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1292 {
1293 DCHECK_LAYER_NEG1_INDEX(layer);
1294 DCHECK(map >= 0 && screen >= 0);
1295 DCHECK(is_valid_rpos(rpos));
1296
1297 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1298
1299 // Screen is not currently loaded, so we have to load and trigger some secrets.
1300 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1301 }
1302
1303 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1304 {
1305 DCHECK_LAYER_NEG1_INDEX(layer);
1306 if (!is_in_world_bounds(x, y))
1307 return 0;
1308 if (layer == -1) return MAPCSET(x, y);
1309
1310 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1311 if (!rpos_handle.scr->is_valid()) return 0;
1312
1313 return rpos_handle.cset();
1314 }
1315
1316 98932978 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1317 {
1318 DCHECK_LAYER_NEG1_INDEX(layer);
1319
3/4
✓ Branch 0 taken 1906392 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 1906392 times.
✗ Branch 3 not taken.
98932978 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1320 return 0;
1321
2/2
✓ Branch 0 taken 81322861 times.
✓ Branch 1 taken 17610117 times.
98932978 if (layer == -1) return MAPFLAG(x, y);
1322
1323 81322861 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1324
2/2
✓ Branch 0 taken 63009646 times.
✓ Branch 1 taken 18313215 times.
81322861 if (!rpos_handle.scr->is_valid()) return 0;
1325
1326 18313215 return rpos_handle.sflag();
1327 98932978 }
1328
1329 2518104 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1330 {
1331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2518104 times.
2518104 if(layer < 1)
1332 {
1333
2/2
✓ Branch 0 taken 5036208 times.
✓ Branch 1 taken 2518104 times.
7554312 for (int32_t i = layer+1; i <= 1; ++i)
1334 {
1335
2/2
✓ Branch 0 taken 4212456 times.
✓ Branch 1 taken 823752 times.
5036208 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1336 {
1337
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4212456 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4212456 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1338 4212456 }
1339 else
1340 {
1341
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 823752 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
823752 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1342 }
1343 5036208 }
1344 2518104 }
1345
1/2
✓ Branch 0 taken 2518104 times.
✗ Branch 1 not taken.
2518104 if(layer==-1) return COMBOTYPE(x,y);
1346
1347 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1348 if (!rpos_handle.scr->is_valid()) return 0;
1349
1350 return rpos_handle.ctype();
1351 2518104 }
1352
1353 // Returns the flag for the combo at the given position.
1354 // This is also known as an "inherent flag".
1355 97162106 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1356 {
1357 DCHECK_LAYER_NEG1_INDEX(layer);
1358
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 97161818 times.
97162106 if (!is_in_world_bounds(x, y))
1359 288 return 0;
1360
2/2
✓ Branch 0 taken 81262990 times.
✓ Branch 1 taken 15898828 times.
97161818 if (layer == -1) return MAPCOMBOFLAG(x, y);
1361
1362 81262990 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1363
2/2
✓ Branch 0 taken 63019559 times.
✓ Branch 1 taken 18243431 times.
81262990 if (!rpos_handle.scr->is_valid()) return 0;
1364
1365 18243431 return rpos_handle.cflag();
1366 97162106 }
1367
1368 11742139 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1369 {
1370 DCHECK_LAYER_ZERO_INDEX(layer);
1371 11742139 auto rpos_handle = get_rpos_handle(rpos, layer);
1372
2/2
✓ Branch 0 taken 6485404 times.
✓ Branch 1 taken 5256735 times.
11742139 if (!rpos_handle.scr->is_valid()) return false;
1373
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 5252170 times.
5256735 if (rpos_handle.sflag() == flag) return true;
1374
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 5214465 times.
5252170 if (rpos_handle.cflag() == flag) return true;
1375 5214465 return false;
1376 11742139 }
1377
1378 1713533 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1379 {
1380 DCHECK(is_valid_rpos(rpos));
1381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1713533 times.
1713533 if (rpos > region_max_rpos) return false;
1382
1383
2/2
✓ Branch 0 taken 11742139 times.
✓ Branch 1 taken 1671263 times.
13413402 for(auto q = 0; q < 7; ++q)
1384 {
1385
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11699869 times.
11742139 if(HASFLAG(flag, q, rpos))
1386 42270 return true;
1387 11699869 }
1388 1671263 return false;
1389 1713533 }
1390
1391 const char *screenstate_string[16] =
1392 {
1393 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "No Return",
1394 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1395 "Boss Locked Chests", "Secrets", "Visited", "Light Beams"
1396 };
1397
1398 34866 void eventlog_mapflags()
1399 {
1400 34866 std::ostringstream oss;
1401
1402 34866 int mi = mapind(cur_map, home_screen);
1403
1/2
✓ Branch 0 taken 34866 times.
✗ Branch 1 not taken.
34866 word g = game->maps[mi] &0x3FFF;
1404
1405
2/4
✓ Branch 0 taken 34866 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34866 times.
✗ Branch 3 not taken.
34866 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1406
2/2
✓ Branch 0 taken 7064 times.
✓ Branch 1 taken 27802 times.
34866 if(g) // Main States
1407 {
1408 static const int order[] =
1409 {
1410 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1411 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1412 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1413 mNEVERRET, mTMPNORET
1414 };
1415
1416
1/2
✓ Branch 0 taken 7064 times.
✗ Branch 1 not taken.
7064 oss << " [";
1417 7064 bool comma = false;
1418
2/2
✓ Branch 0 taken 7064 times.
✓ Branch 1 taken 98896 times.
105960 for(int fl : order)
1419 {
1420
2/2
✓ Branch 0 taken 8984 times.
✓ Branch 1 taken 89912 times.
98896 if(!(g&fl))
1421 89912 continue;
1422 8984 byte ind = byte(log2(double(fl)));
1423
2/2
✓ Branch 0 taken 1920 times.
✓ Branch 1 taken 7064 times.
8984 if(comma)
1424
1/2
✓ Branch 0 taken 1920 times.
✗ Branch 1 not taken.
1920 oss << ", ";
1425
1/2
✓ Branch 0 taken 8984 times.
✗ Branch 1 not taken.
8984 oss << screenstate_string[ind];
1426 8984 comma = true;
1427 }
1428
1/2
✓ Branch 0 taken 7064 times.
✗ Branch 1 not taken.
7064 oss << "]";
1429 7064 }
1430
3/4
✓ Branch 0 taken 34866 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 34830 times.
34866 if(game->xstates[mi]) // ExStates
1431 {
1432
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 oss << " Ex[";
1433 36 bool comma = false;
1434
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1152 times.
1188 for(byte fl = 0; fl < 32; ++fl)
1435 {
1436
3/4
✓ Branch 0 taken 1152 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 1110 times.
1152 if(game->xstates[mi] & (1<<fl))
1437 {
1438
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 36 times.
42 if(comma)
1439
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 oss << ", ";
1440
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 oss << int(fl);
1441 42 comma = true;
1442 42 }
1443 1152 }
1444
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 oss << "]";
1445 36 }
1446 { // ExDoors
1447
2/2
✓ Branch 0 taken 34866 times.
✓ Branch 1 taken 139464 times.
174330 for(int q = 0; q < 4; ++q)
1448 {
1449 139464 bool comma = false;
1450
3/4
✓ Branch 0 taken 139464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139454 times.
✓ Branch 3 taken 10 times.
139464 if(auto v = game->xdoors[mi][q])
1451 {
1452
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(comma)
1453 oss << ",";
1454
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 else oss << " ExDoor";
1455
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 oss << "[" << dirstr[q];
1456
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 80 times.
90 for(int fl = 0; fl < 8; ++fl)
1457
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 18 times.
98 if(v & (1<<fl))
1458
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 oss << " " << int(fl);
1459
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 oss << "]";
1460 10 comma = true;
1461 10 }
1462 139464 }
1463 }
1464
2/4
✓ Branch 0 taken 34866 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34866 times.
34866 Z_eventlog("%s\n", oss.str().c_str());
1465 34866 }
1466
1467 // set specific flag
1468 5614 void setmapflag(mapscr* scr, int32_t flag)
1469 {
1470
2/2
✓ Branch 0 taken 5601 times.
✓ Branch 1 taken 13 times.
5614 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1471 5614 int mi = mapind(cur_map, scr->screen);
1472 5614 setmapflag_mi(scr, mi, flag);
1473 5614 }
1474 57 void setmapflag_homescr(int32_t flag)
1475 {
1476 57 int mi = mapind(cur_map, home_screen);
1477 57 setmapflag_mi(origin_scr, mi, flag);
1478 57 }
1479 2023 void setmapflag_mi(int32_t mi, int32_t flag)
1480 {
1481 2023 byte cscr = mi&((1<<7)-1);
1482 2023 byte cmap = (mi>>7);
1483 2023 mapscr* scr = origin_scr;
1484
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 1189 times.
2023 if (is_in_current_region(cmap, cscr))
1485 1189 scr = get_scr(cmap, cscr);
1486
1487 2023 setmapflag_mi(scr, mi, flag);
1488 2023 }
1489
1490 8474 static void log_state_change(int map, int screen, std::string action)
1491 {
1492
6/6
✓ Branch 0 taken 1913 times.
✓ Branch 1 taken 6561 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8474 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1493 6913 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1494 else
1495 1561 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1496 8474 }
1497
1498 7694 void setmapflag_mi(mapscr* scr, int32_t mi, int32_t flag)
1499 {
1500 7694 byte cscr = mi&((1<<7)-1);
1501 7694 byte cmap = (mi>>7);
1502
1503 7694 float temp=log2((float)flag);
1504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7694 times.
7694 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1505
1506
3/4
✓ Branch 0 taken 7694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6142 times.
7694 if (replay_is_active() && !(game->maps[mi] & flag))
1507
1/2
✓ Branch 0 taken 6142 times.
✗ Branch 1 not taken.
6142 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, state_string));
1508 7694 game->maps[mi] |= flag;
1509
1/2
✓ Branch 0 taken 7694 times.
✗ Branch 1 not taken.
7694 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1510
1511
10/10
✓ Branch 0 taken 5456 times.
✓ Branch 1 taken 2238 times.
✓ Branch 2 taken 3616 times.
✓ Branch 3 taken 1840 times.
✓ Branch 4 taken 3031 times.
✓ Branch 5 taken 585 times.
✓ Branch 6 taken 2877 times.
✓ Branch 7 taken 154 times.
✓ Branch 8 taken 13 times.
✓ Branch 9 taken 2480 times.
10187 if(flag==mSECRET||flag==mITEM||flag==mSPECIALITEM||flag==mLOCKBLOCK||
1512
6/6
✓ Branch 0 taken 2830 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 2685 times.
✓ Branch 3 taken 145 times.
✓ Branch 4 taken 2493 times.
✓ Branch 5 taken 192 times.
2877 flag==mBOSSLOCKBLOCK||flag==mCHEST||flag==mBOSSCHEST||flag==mLOCKEDCHEST)
1513 {
1514 5214 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1515 5214 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1516
1517 5214 std::vector<int32_t> done;
1518
2/2
✓ Branch 0 taken 5099 times.
✓ Branch 1 taken 115 times.
5214 bool looped = (nmap==cmap+1 && nscr==cscr);
1519
1520
6/6
✓ Branch 0 taken 538 times.
✓ Branch 1 taken 5162 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 486 times.
✓ Branch 4 taken 486 times.
✓ Branch 5 taken 5214 times.
5700 while((nmap!=0) && !looped && !(nscr>=128))
1521 {
1522
5/6
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 122 times.
✓ Branch 2 taken 364 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 171 times.
✓ Branch 5 taken 193 times.
486 if((scr->nocarry&flag)!=flag && !(game->maps[((nmap-1)<<7)+nscr] & flag))
1523 {
1524
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1525
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1526
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, state_string));
1527
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1528 193 }
1529
1530 486 cmap=nmap;
1531 486 cscr=nscr;
1532 486 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1533 486 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1534
1535
2/2
✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 486 times.
1966 for(auto it = done.begin(); it != done.end(); it++)
1536 {
1537
2/2
✓ Branch 0 taken 1428 times.
✓ Branch 1 taken 52 times.
1480 if(*it == ((nmap-1)<<7)+nscr)
1538 52 looped = true;
1539 1480 }
1540
1541
1/2
✓ Branch 0 taken 486 times.
✗ Branch 1 not taken.
486 done.push_back(((nmap-1)<<7)+nscr);
1542 }
1543 5214 }
1544 7694 }
1545
1546 void unsetmapflag_home(int32_t flag, bool anyflag)
1547 {
1548 int mi = mapind(cur_map, home_screen);
1549 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1550 }
1551
1552 void unsetmapflag(mapscr* scr, int32_t flag, bool anyflag)
1553 {
1554 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1555 int mi = mapind(cur_map, scr->screen);
1556 unsetmapflag_mi(scr, mi, flag, anyflag);
1557 }
1558
1559 471 void unsetmapflag_mi(int32_t mi, int32_t flag, bool anyflag)
1560 {
1561 471 byte cscr = mi&((1<<7)-1);
1562 471 byte cmap = (mi>>7);
1563 471 mapscr* scr = origin_scr;
1564
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1565 11 scr = get_scr(cmap, cscr);
1566
1567 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1568 471 }
1569
1570 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, int32_t flag, bool anyflag)
1571 {
1572 471 byte cscr = mi&((1<<7)-1);
1573 471 byte cmap = (mi>>7);
1574
1575
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1576 460 game->maps[mi] &= ~flag;
1577
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1578 {
1579 if(!(scr->flags4&fNOITEMRESET))
1580 game->maps[mi] &= ~flag;
1581 }
1582 11 else game->maps[mi] &= ~flag;
1583
1584 471 float temp=log2((float)flag);
1585
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1586
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1587
1588
5/10
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 460 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
471 if(flag==mSECRET||flag==mITEM||flag==mSPECIALITEM||flag==mLOCKBLOCK||
1589
4/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
11 flag==mBOSSLOCKBLOCK||flag==mCHEST||flag==mBOSSCHEST||flag==mLOCKEDCHEST)
1590 {
1591 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1592 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1593
1594 471 std::vector<int32_t> done;
1595
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1596
1597
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1598 {
1599
4/6
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 72 times.
84 if((scr->nocarry&flag)!=flag && (game->maps[((nmap-1)<<7)+nscr] & flag))
1600 {
1601
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1602
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1603 72 }
1604
1605 84 cmap=nmap;
1606 84 cscr=nscr;
1607 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1608 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1609
1610
2/2
✓ Branch 0 taken 546 times.
✓ Branch 1 taken 84 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1611 {
1612
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1613 6 looped = true;
1614 546 }
1615
1616
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1617 }
1618 471 }
1619 471 }
1620
1621 44201525 bool getmapflag(int32_t screen, int32_t flag)
1622 {
1623
2/2
✓ Branch 0 taken 1164399 times.
✓ Branch 1 taken 43037126 times.
44201525 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1624 44201525 return (game->maps[mi] & flag) != 0;
1625 }
1626 162342 bool getmapflag(mapscr* scr, int32_t flag)
1627 {
1628 162342 return getmapflag(scr->screen, flag);
1629 }
1630
1631 59 void setxmapflag(int32_t screen, uint32_t flag)
1632 {
1633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1634 59 setxmapflag_mi(mi, flag);
1635 59 }
1636 61 void setxmapflag_mi(int32_t mi, uint32_t flag)
1637 {
1638
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 40 times.
61 if(game->xstates[mi] & flag) return;
1639 40 byte cscr = mi&((1<<7)-1);
1640 40 byte cmap = (mi>>7);
1641
1642 40 byte temp=(byte)log2((double)flag);
1643
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1644
1645 40 game->xstates[mi] |= flag;
1646 61 }
1647 void unsetxmapflag(int32_t screen, uint32_t flag)
1648 {
1649 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1650 unsetxmapflag_mi(mi, flag);
1651 }
1652 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1653 {
1654 if(!(game->xstates[mi] & flag)) return;
1655 byte cscr = mi&((1<<7)-1);
1656 byte cmap = (mi>>7);
1657 byte temp=(byte)log2((double)flag);
1658 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1659 game->xstates[mi] &= ~flag;
1660 }
1661 29 bool getxmapflag(int32_t screen, uint32_t flag)
1662 {
1663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1664 29 return getxmapflag_mi(mi, flag);
1665 }
1666 471654187 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1667 {
1668 471654187 return (game->xstates[mi] & flag) != 0;
1669 }
1670
1671 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1672 {
1673
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1674 return;
1675
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1676 return;
1677
1678
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1679
1680 4 int cscr = mi % MAPSCRSNORMAL;
1681 4 int cmap = mi / MAPSCRSNORMAL;
1682
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1683
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1684 else
1685 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1686 4 }
1687 471654157 bool getxdoor_mi(uint mi, uint dir, uint ind)
1688 {
1689
3/6
✓ Branch 0 taken 471654157 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 471654157 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 471654157 times.
471654157 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1690 return false;
1691 471654157 return (game->xdoors[mi][dir] & (1<<ind));
1692 471654157 }
1693 13 bool getxdoor(int32_t screen, uint dir, uint ind)
1694 {
1695 13 int mi = mapind(cur_map, screen);
1696 13 return getxdoor_mi(mi,dir,ind);
1697 }
1698
1699 401 void set_doorstate_mi(uint mi, uint dir)
1700 {
1701
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1702 return;
1703 401 setmapflag_mi(mi, mDOOR_UP << dir);
1704
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1705 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1706 401 }
1707 401 void set_doorstate(uint screen, uint dir)
1708 {
1709 401 int mi = mapind(cur_map, screen);
1710 401 set_doorstate_mi(mi, dir);
1711 401 }
1712
1713 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1714 {
1715
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1716 return;
1717 2 setxdoor_mi(mi, dir, ind, state);
1718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1719 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1720 2 }
1721
1722 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1723 {
1724 2 int mi = mapind(cur_map, screen);
1725 2 set_xdoorstate_mi(mi, dir, ind, state);
1726 2 }
1727
1728 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1729 // returns: -1 = not a warp screen
1730 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1731 {
1732 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1733
1734
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1735 return -1;
1736
1737 57 int32_t ring=scr->catchall;
1738 57 int32_t size=QMisc.warp[ring].size;
1739
1740
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1741 return -2;
1742
1743 57 int32_t index=-1;
1744
1745
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1746
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1747 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1748 57 index=i;
1749
1750
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1751 return -3;
1752
1753 57 index = (index+dw)%size;
1754 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1755 57 }
1756
1757 14784919 void update_combo_cycling()
1758 {
1759 14784919 auto& combo_cache = combo_caches::can_cycle;
1760
1761 static int32_t newdata[176];
1762 static int32_t newcset[176];
1763 static bool initialized=false;
1764
1765 // Just a simple bit of optimization
1766
2/2
✓ Branch 0 taken 14784615 times.
✓ Branch 1 taken 304 times.
14784919 if(!initialized)
1767 {
1768
2/2
✓ Branch 0 taken 53504 times.
✓ Branch 1 taken 304 times.
53808 for(int32_t i=0; i<176; i++)
1769 {
1770 53504 newdata[i]=-1;
1771 53504 newcset[i]=-1;
1772 53504 }
1773
1774 304 initialized=true;
1775 304 }
1776
1777 14784919 std::set<uint16_t> restartanim;
1778
1779
1/2
✓ Branch 0 taken 14784919 times.
✗ Branch 1 not taken.
29959206 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1780 15174287 int screen = scr->screen;
1781 int32_t x;
1782
1783
2/2
✓ Branch 0 taken 2670674512 times.
✓ Branch 1 taken 15174287 times.
2685848799 for(int32_t i=0; i<176; i++)
1784 {
1785 2670674512 x=scr->data[i];
1786 2670674512 auto& mini_cmb = combo_cache.minis[x];
1787
2/2
✓ Branch 0 taken 3273932 times.
✓ Branch 1 taken 2667400580 times.
2670674512 if (!mini_cmb.can_cycle)
1788 2667400580 continue;
1789
1790 3273932 newcombo const& cmb = combobuf[x];
1791
1792 //time to restart
1793
4/4
✓ Branch 0 taken 902694 times.
✓ Branch 1 taken 2371238 times.
✓ Branch 2 taken 474434 times.
✓ Branch 3 taken 428260 times.
3273932 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1794 {
1795 428260 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428260 times.
428260 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1797 428260 newdata[i] = c;
1798
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(!(cmb.animflags & AF_CYCLENOCSET))
1799
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428240 times.
428240 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1800
1801
2/2
✓ Branch 0 taken 427216 times.
✓ Branch 1 taken 1044 times.
428260 if(combobuf[c].animflags & AF_CYCLE)
1802 {
1803 1044 restartanim.insert(c);
1804 1044 }
1805 428260 }
1806 3273932 }
1807
1808 15174287 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1809
2/2
✓ Branch 0 taken 2670674512 times.
✓ Branch 1 taken 15174287 times.
2685848799 for(int32_t i=0; i<176; i++)
1810 {
1811
2/2
✓ Branch 0 taken 428260 times.
✓ Branch 1 taken 2670246252 times.
2670674512 if(newdata[i]==-1)
1812 2670246252 continue;
1813
1814 428260 rpos_t rpos = (rpos_t)(rpos_base + i);
1815 428260 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1816 428260 screen_combo_modify_preroutine(rpos_handle);
1817 428260 scr->data[i]=newdata[i];
1818
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(newcset[i]>-1)
1819 428240 scr->cset[i]=newcset[i];
1820 428260 screen_combo_modify_postroutine(rpos_handle);
1821
1822 428260 newdata[i]=-1;
1823 428260 newcset[i]=-1;
1824 428260 }
1825
1826 15174287 word c = scr->numFFC();
1827
2/2
✓ Branch 0 taken 15174287 times.
✓ Branch 1 taken 453640149 times.
468814436 for(word i=0; i<c; i++)
1828 {
1829 453640149 ffcdata& ffc = scr->ffcs[i];
1830 453640149 auto& mini_cmb = combo_cache.minis[ffc.data];
1831
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 453635976 times.
453640149 if (!mini_cmb.can_cycle)
1832 453635976 continue;
1833
1834 4173 newcombo const& cmb = combobuf[ffc.data];
1835
1836 //time to restart
1837
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1838 {
1839 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1841 108 zc_ffc_set(ffc, c);
1842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1843
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1844
1845
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1846 {
1847 60 restartanim.insert(ffc.data);
1848 60 }
1849 108 }
1850 4173 }
1851
1852
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 6755888 times.
15174287 if(get_qr(qr_CMBCYCLELAYERS))
1853 {
1854
2/2
✓ Branch 0 taken 40535328 times.
✓ Branch 1 taken 6755888 times.
47291216 for(int32_t j=1; j<=6; j++)
1855 {
1856 40535328 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1857
2/2
✓ Branch 0 taken 10910129 times.
✓ Branch 1 taken 29625199 times.
40535328 if (!layer_scr)
1858 29625199 continue;
1859
1860
2/2
✓ Branch 0 taken 1920182704 times.
✓ Branch 1 taken 10910129 times.
1931092833 for(int32_t i=0; i<176; i++)
1861 {
1862 1920182704 x=layer_scr->data[i];
1863 1920182704 auto& mini_cmb = combo_cache.minis[x];
1864
2/2
✓ Branch 0 taken 2230121 times.
✓ Branch 1 taken 1917952583 times.
1920182704 if (!mini_cmb.can_cycle)
1865 1917952583 continue;
1866
1867 2230121 newcombo const& cmb = combobuf[x];
1868
1869 //time to restart
1870
4/4
✓ Branch 0 taken 48392 times.
✓ Branch 1 taken 2181729 times.
✓ Branch 2 taken 37470 times.
✓ Branch 3 taken 10922 times.
2230121 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1871 {
1872 10922 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10922 times.
10922 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1874 10922 newdata[i] = c;
1875
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 10864 times.
10922 if(!(cmb.animflags & AF_CYCLENOCSET))
1876
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1877 58 else newcset[i] = layer_scr->cset[i];
1878
1879
2/2
✓ Branch 0 taken 947 times.
✓ Branch 1 taken 9975 times.
10922 if(combobuf[c].animflags & AF_CYCLE)
1880 {
1881 9975 restartanim.insert(c);
1882 9975 }
1883 10922 }
1884 2230121 }
1885
1886
2/2
✓ Branch 0 taken 1920182704 times.
✓ Branch 1 taken 10910129 times.
1931092833 for (int32_t i=0; i<176; i++)
1887 {
1888
2/2
✓ Branch 0 taken 1920171782 times.
✓ Branch 1 taken 10922 times.
1920182704 if(newdata[i]!=-1)
1889 {
1890 10922 layer_scr->data[i]=newdata[i];
1891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10922 times.
10922 if(newcset[i]>-1)
1892 10922 layer_scr->cset[i]=newcset[i];
1893 10922 newdata[i]=-1;
1894 10922 newcset[i]=-1;
1895 10922 }
1896 1920182704 }
1897 10910129 }
1898 6755888 }
1899 15174287 });
1900
1901
2/2
✓ Branch 0 taken 14784919 times.
✓ Branch 1 taken 2657 times.
14787576 for (auto i : restartanim)
1902 {
1903 2657 combobuf[i].tile = combobuf[i].o_tile;
1904 2657 combobuf[i].cur_frame=0;
1905 2657 combobuf[i].aclk = 0;
1906
1/2
✓ Branch 0 taken 2657 times.
✗ Branch 1 not taken.
2657 combo_caches::drawing.refresh(i);
1907 }
1908 14784919 }
1909
1910 1211429562 bool iswater_type(int32_t type)
1911 {
1912 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1913 1211429562 return (combo_class_buf[type].water!=0);
1914 }
1915
1916 bool iswater(int32_t combo)
1917 {
1918 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1919 }
1920 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1921 {
1922 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1923 }
1924
1925 // (x, y) are world coordinates
1926 58800718 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1927 {
1928
8/8
✓ Branch 0 taken 58754555 times.
✓ Branch 1 taken 46163 times.
✓ Branch 2 taken 58714211 times.
✓ Branch 3 taken 40344 times.
✓ Branch 4 taken 58647472 times.
✓ Branch 5 taken 66739 times.
✓ Branch 6 taken 59561 times.
✓ Branch 7 taken 58587911 times.
58800718 if (x<0 || x>=world_w || y<0 || y>=world_h)
1929 212807 return false;
1930
1931 58587911 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
1932 58800718 }
1933
1934 97429633 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1935 {
1936 DCHECK_LAYER_NEG1_INDEX(layer);
1937 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
1938 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
1939
1940 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
1941
2/2
✓ Branch 0 taken 57580095 times.
✓ Branch 1 taken 39849538 times.
97429633 if (get_qr(qr_SMARTER_WATER))
1942 {
1943
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57580095 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57580095 if (DRIEDLAKE) return 0;
1944
5/6
✓ Branch 0 taken 19616230 times.
✓ Branch 1 taken 37963865 times.
✓ Branch 2 taken 6518562 times.
✓ Branch 3 taken 13097668 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518562 times.
57580095 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
1945 {
1946
2/2
✓ Branch 0 taken 37946344 times.
✓ Branch 1 taken 12424338 times.
50370682 for (int32_t m = layer; m <= 1; m++)
1947 {
1948
5/6
✓ Branch 0 taken 24848676 times.
✓ Branch 1 taken 13097668 times.
✓ Branch 2 taken 12424338 times.
✓ Branch 3 taken 12424338 times.
✓ Branch 4 taken 12424338 times.
✗ Branch 5 not taken.
50370682 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
1949
1/2
✓ Branch 0 taken 12424338 times.
✗ Branch 1 not taken.
24848676 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
1950 {
1951 37946344 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
1952
2/2
✓ Branch 0 taken 37273014 times.
✓ Branch 1 taken 673330 times.
37946344 if (checkwater > 0)
1953 {
1954
2/2
✓ Branch 0 taken 673272 times.
✓ Branch 1 taken 58 times.
673330 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
1955 673330 return checkwater;
1956 }
1957 37273014 }
1958 37273014 }
1959 12424338 return 0;
1960 }
1961 else
1962 {
1963
2/2
✓ Branch 0 taken 44497100 times.
✓ Branch 1 taken 42293999 times.
86791099 for(int32_t i=(fullcheck?3:0); i>=0; i--)
1964 {
1965 44497100 int32_t tx2=((i&2)<<2)+x;
1966 44497100 int32_t ty2=((i&1)<<3)+y;
1967 44497100 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
1968 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
1969
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 44475427 times.
44497100 if (!fullcheck)
1970 {
1971 44475427 tx2 = x;
1972 44475427 ty2 = y;
1973
2/2
✓ Branch 0 taken 24969970 times.
✓ Branch 1 taken 19505457 times.
44475427 if(tx2&8) b+=2;
1974
2/2
✓ Branch 0 taken 20628027 times.
✓ Branch 1 taken 23847400 times.
44475427 if(ty2&8) b+=1;
1975 44475427 }
1976
2/2
✓ Branch 0 taken 95107640 times.
✓ Branch 1 taken 43638593 times.
138746233 for (int32_t m = layer; m <= 1; m++)
1977 {
1978 95107640 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
1979
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77371913 times.
95107640 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1980 {
1981
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735727 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735727 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
1982 {
1983 return 0;
1984 }
1985 17735727 }
1986 else
1987 {
1988
4/4
✓ Branch 0 taken 188663 times.
✓ Branch 1 taken 77183250 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 137511 times.
77371913 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
1989 {
1990 137511 return 0;
1991 }
1992 }
1993
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77234402 times.
94970129 if (get_qr(qr_NO_SOLID_SWIM))
1994 {
1995
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 77183250 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 720996 times.
✓ Branch 5 taken 76462254 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 717535 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
77234402 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
1996 {
1997 720996 return 0;
1998 }
1999 76513406 }
2000
3/6
✓ Branch 0 taken 320336 times.
✓ Branch 1 taken 93928797 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320336 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
94249133 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2001 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2002 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2003 {
2004 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2005 }
2006 94249133 }
2007
2008 131503863 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2009
2/2
✓ Branch 0 taken 87337405 times.
✓ Branch 1 taken 527865 times.
87865270 if (ffcIsAt(ffc_handle, tx2, ty2))
2010 {
2011 527865 auto ty = ffc_handle.ctype();
2012
4/6
✓ Branch 0 taken 527865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383640 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527865 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2013 527865 return true;
2014 }
2015
2016 87337405 return false;
2017 87865270 });
2018
2/2
✓ Branch 0 taken 43110728 times.
✓ Branch 1 taken 527865 times.
43638593 if (found_ffc_not_water) return 0;
2019
2020
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 43096055 times.
43110728 if(!i)
2021 {
2022 128109539 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2023
1/2
✓ Branch 0 taken 85013484 times.
✗ Branch 1 not taken.
85013484 if (ffcIsAt(ffc_handle, tx2, ty2))
2024 {
2025 auto ty = ffc_handle.ctype();
2026 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2027 return true;
2028 }
2029
2030 85013484 return false;
2031 85013484 });
2032
1/2
✓ Branch 0 taken 43096055 times.
✗ Branch 1 not taken.
43096055 if (found_ffc_water)
2033 {
2034 if(out_handle) *out_handle = *found_ffc_water;
2035 return found_ffc_water->data();
2036 }
2037 43096055 }
2038
2039 43110728 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2040
2/2
✓ Branch 0 taken 43066234 times.
✓ Branch 1 taken 44494 times.
43110728 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2041
7/12
✓ Branch 0 taken 42785629 times.
✓ Branch 1 taken 280605 times.
✓ Branch 2 taken 10876747 times.
✓ Branch 3 taken 31908882 times.
✓ Branch 4 taken 10398563 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10398563 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
43066234 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2042 {
2043
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757562 times.
758789 if (i == 0)
2044 {
2045
2/2
✓ Branch 0 taken 757553 times.
✓ Branch 1 taken 9 times.
757562 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2046 757562 return checkcombo;
2047 }
2048 1227 }
2049 42308672 }
2050 42293999 return 0;
2051 }
2052 }
2053 else
2054 {
2055 39849538 int32_t b = 0;
2056
2/2
✓ Branch 0 taken 20636485 times.
✓ Branch 1 taken 19213053 times.
39849538 if(x&8) b+=2;
2057
2/2
✓ Branch 0 taken 15456557 times.
✓ Branch 1 taken 24392981 times.
39849538 if(y&8) b+=1;
2058
1/2
✓ Branch 0 taken 39849538 times.
✗ Branch 1 not taken.
39849538 if (get_qr(qr_NO_SOLID_SWIM))
2059 {
2060 if (combobuf[combo].walk&(1<<b))
2061 {
2062 return 0;
2063 }
2064 }
2065
1/2
✓ Branch 0 taken 39849538 times.
✗ Branch 1 not taken.
39849538 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2066
8/8
✓ Branch 0 taken 38150906 times.
✓ Branch 1 taken 1698632 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982961 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1782338 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39849538 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2067 {
2068
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2069 1944029 return combo;
2070 }
2071 38146735 return 0;
2072 }
2073 97670859 }
2074
2075 326 bool isdamage_type(int32_t type)
2076 {
2077
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2078 {
2079 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2080 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2081 return true;
2082 }
2083 326 return false;
2084 326 }
2085
2086 2569060741 bool ispitfall_type(int32_t type)
2087 {
2088 2569060741 return combo_class_buf[type].pit != 0;
2089 }
2090
2091 2569060741 bool ispitfall(int32_t combo)
2092 {
2093 2569060741 return ispitfall_type(combobuf[combo].type);
2094 }
2095
2096 277814771 bool ispitfall(int32_t x, int32_t y)
2097 {
2098
2/2
✓ Branch 0 taken 1454897 times.
✓ Branch 1 taken 276359874 times.
277814771 if(int32_t c = MAPFFCOMBO(x,y))
2099 {
2100 1454897 return ispitfall(c) ? true : false;
2101 }
2102 276359874 int32_t c = MAPCOMBOL(2,x,y);
2103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 276359874 times.
276359874 if(ispitfall(c)) return true;
2104
2/2
✓ Branch 0 taken 263215605 times.
✓ Branch 1 taken 13144269 times.
276359874 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2105 {
2106
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263215605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263215605 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2107 263215605 }
2108 else
2109 {
2110
3/4
✓ Branch 0 taken 3534 times.
✓ Branch 1 taken 13140735 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3534 times.
13144269 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2111 }
2112 276356340 c = MAPCOMBOL(1,x,y);
2113
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 276356316 times.
276356340 if(ispitfall(c)) return true;
2114
2115
2/2
✓ Branch 0 taken 263215605 times.
✓ Branch 1 taken 13140711 times.
276356316 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2116 {
2117
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263215605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263215605 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2118 263215605 }
2119 else
2120 {
2121
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 13127639 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
13140711 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2122 }
2123 276347539 c = MAPCOMBO(x,y);
2124
2/2
✓ Branch 0 taken 70766 times.
✓ Branch 1 taken 276276773 times.
276347539 if(ispitfall(c)) return true;
2125 276276773 return false;
2126 277814771 }
2127
2128 585767144 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2129 {
2130
2/2
✓ Branch 0 taken 9281019 times.
✓ Branch 1 taken 576486125 times.
585767144 if(int32_t c = MAPFFCOMBO(x,y))
2131 {
2132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9281019 times.
9281019 return ispitfall(c) ? c : 0;
2133 }
2134 576486125 int32_t c = MAPCOMBOL(2,x,y);
2135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 576486125 times.
576486125 if(ispitfall(c)) return c;
2136
2137
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43763640 times.
576486125 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2138 {
2139
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2140 532722485 }
2141 else
2142 {
2143
3/4
✓ Branch 0 taken 46726 times.
✓ Branch 1 taken 43716914 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 46726 times.
43763640 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2144 }
2145 576439399 c = MAPCOMBOL(1,x,y);
2146
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 576439121 times.
576439399 if(ispitfall(c)) return c;
2147
2148
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43716636 times.
576439121 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2149 {
2150
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2151 532722485 }
2152 else
2153 {
2154
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43572279 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43716636 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2155 }
2156 576335392 c = MAPCOMBO(x,y);
2157
2/2
✓ Branch 0 taken 177872 times.
✓ Branch 1 taken 576157520 times.
576335392 if(ispitfall(c)) return c;
2158 576157520 return 0;
2159 585767144 }
2160 52 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2161 {
2162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if(int32_t c = MAPFFCOMBO(x,y))
2163 {
2164 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2165 }
2166 52 int32_t c = MAPCOMBOL(2,x,y);
2167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2168
2169
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 46 times.
52 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2170 {
2171
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2172 return nullopt;
2173 6 }
2174 else
2175 {
2176
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
46 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2177 return nullopt;
2178 }
2179 52 c = MAPCOMBOL(1,x,y);
2180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2181
2182
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 46 times.
52 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2183 {
2184
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2185 return nullopt;
2186 6 }
2187 else
2188 {
2189
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
46 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2190 return nullopt;
2191 }
2192 52 c = MAPCOMBO(x,y);
2193
1/2
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
52 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2194 return nullopt;
2195 52 }
2196 5324955 bool check_icy(newcombo const& cmb, int type)
2197 {
2198
1/2
✓ Branch 0 taken 5324955 times.
✗ Branch 1 not taken.
5324955 if(cmb.type != cICY)
2199 5324955 return false;
2200 switch(type)
2201 {
2202 case ICY_BLOCK:
2203 return cmb.usrflags&cflag1;
2204 case ICY_PLAYER:
2205 return cmb.usrflags&cflag2;
2206 }
2207 return false;
2208 5324955 }
2209 1775532 int get_icy(int x, int y, int type)
2210 {
2211 1775532 int32_t c = MAPCOMBOL(2,x,y);
2212
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1775532 times.
1775532 if(check_icy(combobuf[c], type)) return c;
2213
2214 1775532 int screen = get_screen_for_world_xy(x, y);
2215
2216 1775532 mapscr* scr = get_scr_layer_valid(screen, 2);
2217
2/2
✓ Branch 0 taken 430769 times.
✓ Branch 1 taken 1344763 times.
1775532 if (scr)
2218 {
2219
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1344247 times.
1344763 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2220 {
2221
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2222 516 }
2223 else
2224 {
2225
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1344247 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1344247 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2226 }
2227 1344763 }
2228 1775532 c = MAPCOMBOL(1,x,y);
2229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1775532 times.
1775532 if(check_icy(combobuf[c], type)) return c;
2230
2231 1775532 scr = get_scr_layer_valid(screen, 1);
2232
2/2
✓ Branch 0 taken 73612 times.
✓ Branch 1 taken 1701920 times.
1775532 if (scr)
2233 {
2234
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 1699986 times.
1701920 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2235 {
2236
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2237 1934 }
2238 else
2239 {
2240
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1698345 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1699986 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2241 }
2242 1700279 }
2243 1773891 c = MAPCOMBO(x,y);
2244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1773891 times.
1773891 if(check_icy(combobuf[c], type)) return c;
2245 1773891 return 0;
2246 1775532 }
2247
2248 13048712 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2249 {
2250
8/8
✓ Branch 0 taken 13041914 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13033048 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13021416 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 428464 times.
✓ Branch 7 taken 12592952 times.
13048712 if(x<0 || x>=world_w || y<0 || y>=world_h)
2251 455760 return false;
2252
2253 12592952 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2254
2/4
✓ Branch 0 taken 12592952 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12592952 times.
12592952 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2255 return true;
2256
2257 12592952 change_rpos_handle_layer(rpos_handle, 1);
2258
2/2
✓ Branch 0 taken 7565418 times.
✓ Branch 1 taken 5027534 times.
12592952 if (rpos_handle.scr->is_valid())
2259
3/4
✓ Branch 0 taken 5027534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2403 times.
✓ Branch 3 taken 5025131 times.
5027534 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2260 2403 return true;
2261
2262 12590549 change_rpos_handle_layer(rpos_handle, 2);
2263
2/2
✓ Branch 0 taken 10876712 times.
✓ Branch 1 taken 1713837 times.
12590549 if (rpos_handle.scr->is_valid())
2264
2/4
✓ Branch 0 taken 1713837 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1713837 times.
1713837 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2265 return true;
2266
2267 12590549 return false;
2268 13048712 }
2269
2270 6588500 bool isSVLadder(int32_t x, int32_t y)
2271 {
2272 6588500 return checkSV(x, y, mfSIDEVIEWLADDER);
2273 }
2274
2275 6460212 bool isSVPlatform(int32_t x, int32_t y)
2276 {
2277 6460212 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2278 }
2279
2280 6460212 bool checkSVLadderPlatform(int32_t x, int32_t y)
2281 {
2282
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6460212 times.
✓ Branch 2 taken 6458789 times.
✓ Branch 3 taken 1423 times.
6460212 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2283 }
2284
2285 1637 bool isstepable(int32_t combo) //can use ladder on it
2286 {
2287
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2288
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2289 {
2290 if(combobuf[combo].usrflags&cflag4)
2291 {
2292 int32_t ldrid = current_item_id(itype_ladder);
2293 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2294 }
2295 }
2296 6 return false;
2297 1637 }
2298
2299 32780 bool isHSGrabbable(newcombo const& cmb)
2300 {
2301
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 32407 times.
32780 if(cmb.type == cHSGRAB) return true;
2302 32407 return cmb.genflags & cflag1;
2303 32780 }
2304
2305 954 bool isSwitchHookable(newcombo const& cmb)
2306 {
2307
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2308 822 return cmb.genflags & cflag2;
2309 954 }
2310
2311 61401 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2312 {
2313 61401 rpos_t cpos = rpos_t::None;
2314
2/2
✓ Branch 0 taken 64592 times.
✓ Branch 1 taken 125993 times.
61401 if(out_rpos)
2315 {
2316 125993 int32_t id = MAPCOMBO2(layer-1,x,y);
2317
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 97359 times.
125993 if(id > 0)
2318 {
2319 97359 newcombo const& cmb = combobuf[id];
2320
4/4
✓ Branch 0 taken 32738 times.
✓ Branch 1 taken 64621 times.
✓ Branch 2 taken 32296 times.
✓ Branch 3 taken 32325 times.
97359 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2321 32767 }
2322 61401 }
2323
2324 125993 ffcdata* ffc = nullptr;
2325
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3393 times.
125993 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2326 {
2327 10361 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2328
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 115 times.
6968 if (ffcIsAt(ffc_handle, x, y))
2329 {
2330 115 auto& cmb = ffc_handle.combo();
2331
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 36 times.
115 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2332 {
2333 79 ffc = ffc_handle.ffc;
2334 79 return false;
2335 }
2336 36 }
2337 6889 return true;
2338 6896 });
2339 3393 }
2340
2341
4/4
✓ Branch 0 taken 61401 times.
✓ Branch 1 taken 64592 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 60959 times.
125993 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2342
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28382 times.
125993 if (out_ffc && ffc) *out_ffc = ffc;
2343
2/2
✓ Branch 0 taken 65034 times.
✓ Branch 1 taken 60959 times.
125993 return (cpos != rpos_t::None || ffc);
2344 }
2345
2346 5195 bool ishookshottable(int32_t bx, int32_t by)
2347 {
2348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5195 times.
5195 if(!_walkflag(bx,by,1))
2349 return true;
2350
2351
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5187 times.
5195 if (collide_object(bx, by, 1, 1))
2352 8 return false;
2353
2354 5187 bool ret = true;
2355
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 1900 times.
17461 for(int32_t i=2; i>=0; i--)
2356 {
2357 15561 int32_t c = MAPCOMBO2(i-1,bx,by);
2358 15561 int32_t t = combobuf[c].type;
2359
2360
6/6
✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 10374 times.
✓ Branch 2 taken 3853 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1900 times.
✓ Branch 5 taken 1953 times.
15561 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2361
2362
3/4
✓ Branch 0 taken 11321 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13227 bool dried = (iswater_type(t) && DRIEDLAKE);
2363
2364 12274 int32_t b=1;
2365
2366
2/2
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 6165 times.
12274 if(bx&8) b<<=2;
2367
2368
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 8433 times.
12274 if(by&8) b<<=1;
2369
2370
7/8
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 10180 times.
✓ Branch 2 taken 2094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 979 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 904 times.
12274 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2371 904 ret = false;
2372 12274 }
2373
2374 1900 return ret;
2375 5195 }
2376
2377 10111 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2378 {
2379
4/4
✓ Branch 0 taken 9532 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9532 times.
✓ Branch 3 taken 579 times.
10111 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2380 {
2381 579 int pos = COMBOPOS(s->stairx,s->stairy);
2382 579 s->data[pos] = s->secretcombo[sSTAIRS];
2383 579 s->cset[pos] = s->secretcset[sSTAIRS];
2384 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2385
2386
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2387 {
2388 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2389 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2390 256 }
2391
2392 579 return true;
2393 }
2394
2395 9532 return false;
2396 10111 }
2397
2398 51767 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2399 {
2400 DCHECK(base_scr->is_valid());
2401
2402 51767 screen_handles_t screen_handles{};
2403 51767 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2404 51767 return screen_handles;
2405 }
2406
2407 56553984 screen_handles_t create_screen_handles(mapscr* base_scr)
2408 {
2409 DCHECK(get_scr(base_scr->screen) == base_scr);
2410 DCHECK(base_scr->is_valid());
2411
2412 56553984 int screen = base_scr->screen;
2413 screen_handles_t screen_handles;
2414 56553984 screen_handles[0] = {base_scr, base_scr, screen, 0};
2415
2/2
✓ Branch 0 taken 339323904 times.
✓ Branch 1 taken 56553984 times.
395877888 for (int i = 1; i <= 6; i++)
2416 339323904 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2417 56553984 return screen_handles;
2418 }
2419
2420 106202 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2421 {
2422 106202 mapscr* scr = screen_handles[0].scr;
2423 106202 bool didit=false;
2424
2425
2/2
✓ Branch 0 taken 106202 times.
✓ Branch 1 taken 18691552 times.
18797754 for(int32_t i=0; i<176; i++)
2426 {
2427 18691552 newcombo const& cmb = combobuf[scr->data[i]];
2428
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18691226 times.
18691552 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2429
4/4
✓ Branch 0 taken 18689693 times.
✓ Branch 1 taken 1533 times.
✓ Branch 2 taken 1102 times.
✓ Branch 3 taken 18688591 times.
18691226 if((cmb.type == what1) || (cmb.type== what2))
2430 {
2431 2635 scr->data[i]++;
2432 2635 didit=true;
2433 2635 }
2434 18691226 }
2435
2436
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106110 times.
106202 if (do_layers)
2437 {
2438
2/2
✓ Branch 0 taken 636660 times.
✓ Branch 1 taken 106110 times.
742770 for(int32_t j=1; j<=6; j++)
2439 {
2440 636660 mapscr* layer_scr = screen_handles[j].scr;
2441
2/2
✓ Branch 0 taken 173044 times.
✓ Branch 1 taken 463616 times.
636660 if (!layer_scr) continue;
2442
2443
2/2
✓ Branch 0 taken 30455744 times.
✓ Branch 1 taken 173044 times.
30628788 for(int32_t i=0; i<176; i++)
2444 {
2445 30455744 newcombo const& cmb = combobuf[layer_scr->data[i]];
2446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30455744 times.
30455744 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2447
4/4
✓ Branch 0 taken 30455661 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30455396 times.
30455744 if((cmb.type== what1) || (cmb.type== what2))
2448 {
2449 348 layer_scr->data[i]++;
2450 348 didit=true;
2451 348 }
2452 30455744 }
2453 173044 }
2454 106110 }
2455
2456 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2457
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106202 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2458 {
2459 20406 word c = scr->numFFC();
2460
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2461 {
2462 73350 ffcdata* ffc = &scr->ffcs[i];
2463 73350 newcombo const& cmb = combobuf[ffc->data];
2464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2465
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2466 {
2467 zc_ffc_modify(*ffc, 1);
2468 didit=true;
2469 }
2470 73350 }
2471 20406 }
2472
2473 106202 return didit;
2474 }
2475
2476 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2477 {
2478 14 int screen = screen_handles[0].scr->screen;
2479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2480 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2481 }
2482 471654158 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2483 {
2484 471654158 bool didit=false;
2485
2/2
✓ Branch 0 taken 471622063 times.
✓ Branch 1 taken 32095 times.
471654158 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2486
2487 32095 mapscr* s = screen_handles[0].scr;
2488 32095 int screen = s->screen;
2489 32095 bool is_active_screen = is_in_current_region(s);
2490
2491 26530479 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2492
4/4
✓ Branch 0 taken 26486768 times.
✓ Branch 1 taken 11616 times.
✓ Branch 2 taken 26484974 times.
✓ Branch 3 taken 1794 times.
26498384 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2493 1794 didit = true;
2494
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 26432963 times.
26496590 else switch (rpos_handle.ctype())
2495 {
2496 case cLOCKBLOCK: case cLOCKBLOCK2:
2497 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2498 case cCHEST: case cCHEST2:
2499 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2500 case cBOSSCHEST: case cBOSSCHEST2:
2501 {
2502 63627 auto& cmb = rpos_handle.combo();
2503
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2504
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2505 {
2506 29 rpos_handle.increment_data();
2507 29 didit=true;
2508 29 }
2509 62059 break;
2510 }
2511 }
2512 26498384 });
2513
2514
4/4
✓ Branch 0 taken 32054 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 22434 times.
✓ Branch 3 taken 9620 times.
32095 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2515 {
2516 22434 word c = s->numFFC();
2517 22434 int screen_index_offset = get_region_screen_offset(screen);
2518
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 22434 times.
59274 for (uint8_t i = 0; i < c; i++)
2519 {
2520 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2521 36840 auto& cmb = ffc_handle.combo();
2522
3/4
✓ Branch 0 taken 36840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36824 times.
✓ Branch 3 taken 16 times.
36840 if(triggers && force_ex_trigger_ffc_any(ffc_handle, xflag))
2523 16 didit = true;
2524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2525 {
2526 case cLOCKBLOCK: case cLOCKBLOCK2:
2527 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2528 case cCHEST: case cCHEST2:
2529 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2530 case cBOSSCHEST: case cBOSSCHEST2:
2531 {
2532 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2533 if(cmb.attribytes[5] == xflag)
2534 {
2535 zc_ffc_modify(*ffc_handle.ffc, 1);
2536 didit=true;
2537 }
2538 break;
2539 }
2540 }
2541 36840 }
2542 22434 }
2543
2544 32095 return didit;
2545 471654158 }
2546
2547 14687195 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2548 {
2549 14687195 int screen = screen_handles[0].screen;
2550
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14299362 times.
14687195 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2551 14687195 clear_xstatecombos_mi(screen_handles, mi, triggers);
2552 14687195 }
2553
2554 14739192 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2555 {
2556
2/2
✓ Branch 0 taken 471654144 times.
✓ Branch 1 taken 14739192 times.
486393336 for (int q = 0; q < 32; ++q)
2557 {
2558 471654144 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2559 471654144 }
2560 14739192 }
2561
2562 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2563 {
2564 int screen = screen_handles[0].screen;
2565 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2566 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2567 }
2568 471654144 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2569 {
2570 471654144 bool didit=false;
2571
2/2
✓ Branch 0 taken 471649320 times.
✓ Branch 1 taken 4824 times.
471654144 if (!getxdoor_mi(mi, dir, ind)) return false;
2572
2573 4824 mapscr* scr = screen_handles[0].scr;
2574 4824 int screen = scr->screen;
2575 4824 bool is_active_screen = is_in_current_region(scr);
2576
2577 3400920 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2578
3/4
✓ Branch 0 taken 3396096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
✓ Branch 3 taken 3396038 times.
3396096 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2579 58 didit = true;
2580 else; //future door combo types?
2581 3396096 });
2582
2583
2/4
✓ Branch 0 taken 4824 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4824 times.
✗ Branch 3 not taken.
4824 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2584 {
2585 4824 word c = scr->numFFC();
2586 4824 int screen_index_offset = get_region_screen_offset(screen);
2587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4824 times.
4824 for (uint8_t i = 0; i < c; i++)
2588 {
2589 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2590 if (triggers && force_ex_door_trigger_ffc_any(ffc_handle, dir, ind))
2591 didit = true;
2592 else; //future door combo types?
2593 }
2594 4824 }
2595
2596 4824 return didit;
2597 471654144 }
2598
2599 14687195 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2600 {
2601 14687195 int screen = screen_handles[0].screen;
2602
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14299362 times.
14687195 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2603 14687195 return clear_xdoors_mi(screen_handles, mi, triggers);
2604 }
2605
2606 14739192 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2607 {
2608
2/2
✓ Branch 0 taken 58956768 times.
✓ Branch 1 taken 14739192 times.
73695960 for (int dir = 0; dir < 4; ++dir)
2609
2/2
✓ Branch 0 taken 471654144 times.
✓ Branch 1 taken 58956768 times.
530610912 for (int q = 0; q < 8; ++q)
2610 530610912 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2611 14739192 }
2612
2613 763 bool remove_lockblocks(const screen_handles_t& screen_handles)
2614 {
2615 763 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2616 }
2617
2618 98 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2619 {
2620 98 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2621 }
2622
2623 76553 bool remove_chests(const screen_handles_t& screen_handles)
2624 {
2625 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2626 }
2627
2628 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2629 {
2630 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2631 }
2632
2633 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2634 {
2635 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2636 }
2637
2638 1384359 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2639 {
2640 1384359 int32_t ct=rpos_handle.ctype();
2641
2642
6/6
✓ Branch 0 taken 1383739 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1383487 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1383379 times.
✓ Branch 5 taken 108 times.
1384359 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2643 1383379 return;
2644
2645 2465 auto [cx, cy] = rpos_handle.xy();
2646
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2647 {
2648 case cL_STATUE:
2649 620 cx += 4;
2650 620 cy += 7;
2651 620 break;
2652
2653 case cR_STATUE:
2654 252 cx -= 8;
2655 252 cy -= 1;
2656 252 break;
2657
2658 case cC_STATUE:
2659 108 break;
2660 }
2661
2662
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2663 {
2664 // Finds the smallest enemy ID
2665
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2666 {
2667 346 guys.del(j);
2668 346 }
2669 1485 }
2670 1384359 }
2671
2672 15 static int32_t findtrigger(int32_t screen)
2673 {
2674 15 int32_t checkflag=0;
2675 15 int32_t ret = 0;
2676
2677 mapscr* screens[7];
2678
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2679 {
2680 105 screens[j] = get_scr_layer_valid(screen, j);
2681 105 }
2682
2683 15 bool sflag = false;
2684
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2685 {
2686
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2687 {
2688 26752 mapscr* scr = screens[layer+1];
2689
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2690
2691
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2692 8272 checkflag = scr->sflag[j];
2693 else
2694 8272 checkflag = combobuf[scr->data[j]].flag;
2695 16544 sflag = !sflag;
2696
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2697
2698
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2699 {
2700 case mfANYFIRE:
2701 case mfSTRONGFIRE:
2702 case mfMAGICFIRE:
2703 case mfDIVINEFIRE:
2704 case mfARROW:
2705 case mfSARROW:
2706 case mfGARROW:
2707 case mfSBOMB:
2708 case mfBOMB:
2709 case mfBRANG:
2710 case mfMBRANG:
2711 case mfFBRANG:
2712 case mfWANDMAGIC:
2713 case mfREFMAGIC:
2714 case mfREFFIREBALL:
2715 case mfSWORD:
2716 case mfWSWORD:
2717 case mfMSWORD:
2718 case mfXSWORD:
2719 case mfSWORDBEAM:
2720 case mfWSWORDBEAM:
2721 case mfMSWORDBEAM:
2722 case mfXSWORDBEAM:
2723 case mfHOOKSHOT:
2724 case mfWAND:
2725 case mfHAMMER:
2726 case mfSTRIKE:
2727 10 ret += 1;
2728 10 break;
2729 }
2730 16544 }
2731 2640 }
2732
2733 15 return ret;
2734 }
2735
2736 11739 static void log_trigger_secret_reason(TriggerSource source)
2737 {
2738
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11300 times.
11739 if (source == TriggerSource::Singular)
2739 {
2740 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2741 439 }
2742 else
2743 {
2744 11300 const char* source_str = "";
2745
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7178 times.
✓ Branch 3 taken 856 times.
✓ Branch 4 taken 2734 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 52 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11300 switch (source)
2746 {
2747 case TriggerSource::Singular: break;
2748 7178 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2749 856 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2750 2734 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2751 475 case TriggerSource::Script: source_str = "a script"; break;
2752 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2753 52 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2754 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2755 case TriggerSource::SCC: source_str = "SCC"; break;
2756 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2757 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2758 }
2759 11300 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2760 }
2761 11739 }
2762
2763 // single:
2764 // >-1 : the singular triggering combo
2765 // -1: triggered by some other cause
2766 11531 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2767 {
2768 11531 log_trigger_secret_reason(source);
2769
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11092 times.
11531 if (single < 0)
2770 11092 get_screen_state(scr->screen).triggered_secrets = true;
2771
2772 11531 bool do_replay_comment = true;
2773 11531 bool from_active_screen = true;
2774 11531 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2775
2776 // Respect secret state carryovers for active screens.
2777
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11092 times.
11531 if (single >= 0) return;
2778 11092 int flag = mSECRET;
2779 11092 int cmap = scr->map;
2780 11092 int cscr = scr->screen;
2781 11092 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2782 11092 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2783
2784 11092 std::vector<int32_t> done;
2785
2/2
✓ Branch 0 taken 10905 times.
✓ Branch 1 taken 187 times.
11092 bool looped = (nmap==cmap+1 && nscr==cscr);
2786
2787
6/6
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 11015 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 552 times.
✓ Branch 4 taken 552 times.
✓ Branch 5 taken 11092 times.
11644 while((nmap!=0) && !looped && !(nscr>=128))
2788 {
2789
9/10
✓ Branch 0 taken 385 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 301 times.
✓ Branch 4 taken 74 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 74 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 70 times.
552 if (nmap - 1 == cur_map && is_in_current_region(nscr) && (scr->nocarry&flag)!=flag && !get_screen_state(nscr).triggered_secrets)
2790 {
2791
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2792
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2793
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2794 4 }
2795
2796 552 cmap=nmap;
2797 552 cscr=nscr;
2798 552 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2799 552 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2800
2801
2/2
✓ Branch 0 taken 1101 times.
✓ Branch 1 taken 552 times.
1653 for(auto it = done.begin(); it != done.end(); it++)
2802 {
2803
2/2
✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 77 times.
1101 if(*it == ((nmap-1)<<7)+nscr)
2804 77 looped = true;
2805 1101 }
2806
2807
1/2
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
552 done.push_back(((nmap-1)<<7)+nscr);
2808 }
2809 11531 }
2810
2811 2437 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2812 {
2813 2437 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2814 2437 }
2815
2816 18008 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2817 {
2818 18008 mapscr* scr = screen_handles[0].scr;
2819 18008 int screen = scr->screen;
2820
2821 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2822 // slopes in sideview mode (which required loading nearby screens in loadscr).
2823 // TODO(replays): This should just use `screen`.
2824
3/4
✓ Branch 0 taken 18008 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 17469 times.
18008 if (replay_is_active() && do_replay_comment)
2825
4/6
✓ Branch 0 taken 11535 times.
✓ Branch 1 taken 5934 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11535 times.
✓ Branch 4 taken 17469 times.
✗ Branch 5 not taken.
17469 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2826
2827
2/2
✓ Branch 0 taken 6473 times.
✓ Branch 1 taken 11535 times.
18008 if (from_active_screen)
2828 {
2829 5443703 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2830 5432168 auto cid = handle.data();
2831 5432168 auto& cmb = handle.combo();
2832
4/4
✓ Branch 0 taken 5430435 times.
✓ Branch 1 taken 230393 times.
✓ Branch 2 taken 1688 times.
✓ Branch 3 taken 182 times.
5662698 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
2833 {
2834 230575 auto& trig = cmb.triggers[idx];
2835
3/4
✓ Branch 0 taken 66456 times.
✓ Branch 1 taken 163937 times.
✓ Branch 2 taken 182 times.
✗ Branch 3 not taken.
230575 if (trig.triggerflags[2] & combotriggerSECRETSTR)
2836 {
2837 163937 do_trigger_combo(handle, idx, ctrigSECRETS);
2838
2/4
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 163892 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
163937 if(handle.data() != cid) break;
2839 163892 }
2840 230530 }
2841 5432168 });
2842 11535 }
2843
2844 18008 int32_t ft=0; //Flag trigger?
2845 18008 int32_t msflag=0; // Misc. secret flag
2846
2847
2/2
✓ Branch 0 taken 3169408 times.
✓ Branch 1 taken 18008 times.
3187416 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2848 {
2849
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3092144 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3169408 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2850
2851 // Remember the misc. secret flag; if triggered, use this instead
2852
4/4
✓ Branch 0 taken 114509 times.
✓ Branch 1 taken 2978074 times.
✓ Branch 2 taken 49462 times.
✓ Branch 3 taken 65047 times.
3092583 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2853 65047 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2854
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2980306 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3027536 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2855 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2856 else
2857 3027305 msflag=0;
2858
2859
4/4
✓ Branch 0 taken 921256 times.
✓ Branch 1 taken 2171327 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 921184 times.
3092583 if(!high16only || single>=0)
2860 {
2861 2171399 int32_t newflag = -1;
2862
2863
2/2
✓ Branch 0 taken 4342798 times.
✓ Branch 1 taken 2171399 times.
6514197 for(int32_t iter=0; iter<2; ++iter)
2864 {
2865 4342798 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2866
2867
2/2
✓ Branch 0 taken 2171399 times.
✓ Branch 1 taken 2171399 times.
4342798 if(iter==1) checkflag=scr->sflag[i]; //Placed
2868
2869 4342798 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2870
2/2
✓ Branch 0 taken 4330564 times.
✓ Branch 1 taken 12234 times.
4342798 if (ft != -1) //Change the combos for the secret
2871 {
2872 // Use misc. secret flag instead if one is present
2873
2/2
✓ Branch 0 taken 12202 times.
✓ Branch 1 taken 32 times.
12234 if(msflag!=0)
2874 32 ft=msflag;
2875
2876 12234 rpos_handle_t rpos_handle;
2877
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2878 {
2879 5867 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2880 5867 screen_combo_modify_preroutine(rpos_handle);
2881 5867 }
2882
2883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12234 times.
12234 if(ft==sSECNEXT)
2884 {
2885 scr->data[i]++;
2886 }
2887 else
2888 {
2889 12234 scr->data[i] = scr->secretcombo[ft];
2890 12234 scr->cset[i] = scr->secretcset[ft];
2891 }
2892 12234 newflag = scr->secretflag[ft];
2893
2894
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2895 5867 screen_combo_modify_postroutine(rpos_handle);
2896 12234 }
2897 4342798 }
2898
2899
2/2
✓ Branch 0 taken 2159171 times.
✓ Branch 1 taken 12228 times.
2171399 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2900
2901
2/2
✓ Branch 0 taken 13028394 times.
✓ Branch 1 taken 2171399 times.
15199793 for(int32_t j=1; j<=6; j++) //Layers
2902 {
2903 13028394 mapscr* layer_scr = screen_handles[j].scr;
2904
2/2
✓ Branch 0 taken 3186325 times.
✓ Branch 1 taken 9842069 times.
13028394 if (!layer_scr) continue;
2905
2906
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3185600 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3186325 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2907
2908 3186325 int32_t newflag2 = -1;
2909
2910 // Remember the misc. secret flag; if triggered, use this instead
2911
4/4
✓ Branch 0 taken 14183 times.
✓ Branch 1 taken 3172142 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9410 times.
3186325 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2912 9410 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2913
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3049984 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3176915 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2914 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2915 else
2916 3176544 msflag=0;
2917
2918
2/2
✓ Branch 0 taken 6372650 times.
✓ Branch 1 taken 3186325 times.
9558975 for(int32_t iter=0; iter<2; ++iter)
2919 {
2920 6372650 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2921
2/2
✓ Branch 0 taken 3186325 times.
✓ Branch 1 taken 3186325 times.
6372650 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2922
2923 6372650 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2924
2/2
✓ Branch 0 taken 6372172 times.
✓ Branch 1 taken 478 times.
6372650 if (ft != -1) //Change the combos for the secret
2925 {
2926 // Use misc. secret flag instead if one is present
2927
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
2928 2 ft=msflag;
2929
2930
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
2931 {
2932 layer_scr->data[i]++;
2933 }
2934 else
2935 {
2936 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
2937 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
2938 }
2939 478 newflag2 = layer_scr->secretflag[ft];
2940 478 int32_t c=layer_scr->data[i];
2941 478 int32_t cs=layer_scr->cset[i];
2942
2943
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
2944 {
2945 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
2946 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
2947 }
2948 478 }
2949 6372650 }
2950
2951
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3185847 times.
3186325 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
2952 3186325 }
2953 2171399 }
2954 3092583 }
2955
2956 18008 word c = scr->numFFC();
2957
2/2
✓ Branch 0 taken 506903 times.
✓ Branch 1 taken 18008 times.
524911 for(word i=0; i<c; i++) //FFC 'trigger flags'
2958 {
2959
3/4
✓ Branch 0 taken 492983 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
506903 if(single>=0) if(i+176!=single) continue;
2960
2961
3/4
✓ Branch 0 taken 166605 times.
✓ Branch 1 taken 326378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166605 times.
492983 if((!high16only)||(single>=0))
2962 {
2963 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
2964 {
2965 326378 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
2966 //No placed flags yet
2967
2968 326378 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2969
2/2
✓ Branch 0 taken 326347 times.
✓ Branch 1 taken 31 times.
326378 if (ft != -1) //Change the ffc's combo
2970 {
2971
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
2972 {
2973 zc_ffc_modify(scr->ffcs[i], 1);
2974 }
2975 else
2976 {
2977 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
2978 31 scr->ffcs[i].cset = scr->secretcset[ft];
2979 }
2980 31 }
2981 }
2982 326378 }
2983 492983 }
2984
2985
2/2
✓ Branch 0 taken 15611 times.
✓ Branch 1 taken 2397 times.
18008 if(checktrigger) //Hit all triggers->16-31
2986 {
2987 2397 checktrigger=false;
2988
2989
2/2
✓ Branch 0 taken 2388 times.
✓ Branch 1 taken 9 times.
2397 if(scr->flags6&fTRIGGERF1631)
2990 {
2991 9 int32_t tr = findtrigger(screen); //Normal flags
2992
2993
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
2994 {
2995 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
2996 5 goto endhe;
2997 }
2998 4 }
2999 2392 }
3000
3001
2/2
✓ Branch 0 taken 3168528 times.
✓ Branch 1 taken 18003 times.
3186531 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3002 {
3003 //If it's an enemies->secret screen, only do the high 16 if told to
3004 //That way you can have secret and burn/bomb entrance separately
3005 3168528 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3006
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 387904 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3083344 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3168528 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3007 {
3008 3102880 int32_t newflag = -1;
3009
3010
2/2
✓ Branch 0 taken 6205760 times.
✓ Branch 1 taken 3102880 times.
9308640 for(int32_t iter=0; iter<2; ++iter)
3011 {
3012 6205760 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3013
3014
2/2
✓ Branch 0 taken 3102880 times.
✓ Branch 1 taken 3102880 times.
6205760 if(iter==1) checkflag=scr->sflag[i]; //Placed
3015
3016
4/4
✓ Branch 0 taken 161183 times.
✓ Branch 1 taken 6044577 times.
✓ Branch 2 taken 94853 times.
✓ Branch 3 taken 66330 times.
6205760 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3017 {
3018 66330 rpos_handle_t rpos_handle;
3019
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56378 times.
66330 if (from_active_screen)
3020 {
3021 56378 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3022 56378 screen_combo_modify_preroutine(rpos_handle);
3023 56378 }
3024
3025 66330 scr->data[i] = scr->secretcombo[checkflag-16+4];
3026 66330 scr->cset[i] = scr->secretcset[checkflag-16+4];
3027 66330 newflag = scr->secretflag[checkflag-16+4];
3028
3029
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56378 times.
66330 if (from_active_screen)
3030 56378 screen_combo_modify_postroutine(rpos_handle);
3031 66330 }
3032 6205760 }
3033
3034
2/2
✓ Branch 0 taken 3036574 times.
✓ Branch 1 taken 66306 times.
3102880 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3035
3036
2/2
✓ Branch 0 taken 18617280 times.
✓ Branch 1 taken 3102880 times.
21720160 for(int32_t j=1; j<=6; j++) //Layers
3037 {
3038 18617280 mapscr* layer_scr = screen_handles[j].scr;
3039
2/2
✓ Branch 0 taken 4867280 times.
✓ Branch 1 taken 13750000 times.
18617280 if (!layer_scr) continue;
3040
3041 4867280 int32_t newflag2 = -1;
3042
3043
2/2
✓ Branch 0 taken 9734560 times.
✓ Branch 1 taken 4867280 times.
14601840 for(int32_t iter=0; iter<2; ++iter)
3044 {
3045 9734560 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3046
3047
2/2
✓ Branch 0 taken 4867280 times.
✓ Branch 1 taken 4867280 times.
9734560 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3048
3049
4/4
✓ Branch 0 taken 151247 times.
✓ Branch 1 taken 9583313 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19625 times.
9734560 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3050 {
3051 19625 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3052 19625 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3053 19625 newflag2 = layer_scr->secretflag[checkflag-16+4];
3054 19625 }
3055 9734560 }
3056
3057
2/2
✓ Branch 0 taken 4847655 times.
✓ Branch 1 taken 19625 times.
4867280 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3058 4867280 }
3059 3102880 }
3060 3168528 }
3061
3062
2/2
✓ Branch 0 taken 506743 times.
✓ Branch 1 taken 18003 times.
524746 for(word i=0; i<c; i++) // FFCs
3063 {
3064
6/6
✓ Branch 0 taken 466852 times.
✓ Branch 1 taken 39891 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 491376 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
506743 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3065 {
3066 494906 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3067
3068 //No placed flags yet
3069
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 494838 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
494906 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3070 {
3071
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3072 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3073 else
3074 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3075 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3076 12 }
3077 494906 }
3078 524746 }
3079
3080 endhe:
3081
3082
1/2
✓ Branch 0 taken 18008 times.
✗ Branch 1 not taken.
18008 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3083 {
3084 if (from_active_screen)
3085 activated_timed_warp = true;
3086 scr->timedwarptics = 0;
3087 }
3088 18008 }
3089
3090 // x,y are world coordinates.
3091 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3092 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3093 13509108 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3094 {
3095
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13509108 times.
13509108 if (!is_in_world_bounds(x, y)) return false;
3096
3097 13509108 bool found_cflag = false;
3098 13509108 bool found_nflag = false;
3099 13509108 bool single16 = false;
3100 13509108 rpos_t rpos = rpos_t::None;
3101
3102
2/2
✓ Branch 0 taken 13507024 times.
✓ Branch 1 taken 94551564 times.
108058588 for (int32_t layer = -1; layer < 6; layer++)
3103 {
3104
2/2
✓ Branch 0 taken 94549480 times.
✓ Branch 1 taken 2084 times.
94551564 if (MAPFLAG2(layer, x, y) == flag)
3105 {
3106 2084 found_nflag = true;
3107 2084 break;
3108 }
3109 94549480 }
3110
3111
2/2
✓ Branch 0 taken 13508804 times.
✓ Branch 1 taken 94562480 times.
108071284 for (int32_t layer = -1; layer < 6; layer++)
3112 {
3113
2/2
✓ Branch 0 taken 94562176 times.
✓ Branch 1 taken 304 times.
94562480 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3114 {
3115 304 found_cflag = true;
3116 304 break;
3117 }
3118 94562176 }
3119
3120
2/2
✓ Branch 0 taken 94563756 times.
✓ Branch 1 taken 13509108 times.
108072864 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3121 {
3122
2/2
✓ Branch 0 taken 94549168 times.
✓ Branch 1 taken 14588 times.
94563756 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3123 {
3124
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14476 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14588 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3125 {
3126 112 rpos = COMBOPOS_REGION(x, y);
3127 112 }
3128
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14424 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14476 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3129 {
3130 52 rpos = COMBOPOS_REGION(x, y);
3131 52 single16 = true;
3132 52 }
3133 14588 }
3134
3135
2/2
✓ Branch 0 taken 94561628 times.
✓ Branch 1 taken 2128 times.
94563756 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3136 {
3137
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3138 {
3139 255 rpos = COMBOPOS_REGION(x, y);
3140 255 }
3141
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3142 {
3143 20 rpos = COMBOPOS_REGION(x, y);
3144 20 single16 = true;
3145 20 }
3146 2128 }
3147 94563756 }
3148
3149 13509108 out_rpos = rpos;
3150 13509108 out_single16 = single16;
3151
4/4
✓ Branch 0 taken 13507024 times.
✓ Branch 1 taken 2084 times.
✓ Branch 2 taken 13506722 times.
✓ Branch 3 taken 302 times.
13509108 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3152 13509108 }
3153
3154 4458043 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3155 {
3156
8/8
✓ Branch 0 taken 4457803 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4455906 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4455386 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4454434 times.
4458043 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3157
3158 4454434 mapscr* scr = NULL;
3159 4454434 int32_t screen = -1;
3160 4454434 rpos_t trigger_rpos = rpos_t::None;
3161 4454434 bool single16 = false;
3162
3163 4454434 std::vector<std::pair<int, int>> coords;
3164
1/2
✓ Branch 0 taken 4454434 times.
✗ Branch 1 not taken.
4454434 coords.push_back({x, y});
3165
1/2
✓ Branch 0 taken 4454434 times.
✗ Branch 1 not taken.
4454434 coords.push_back({x + 15, y});
3166
1/2
✓ Branch 0 taken 4454434 times.
✗ Branch 1 not taken.
4454434 coords.push_back({x, y + 15});
3167
1/2
✓ Branch 0 taken 4454434 times.
✗ Branch 1 not taken.
4454434 coords.push_back({x + 15, y + 15});
3168 4454434 std::vector<rpos_t> rposes_seen;
3169
2/2
✓ Branch 0 taken 4452037 times.
✓ Branch 1 taken 17812454 times.
84487711 for (auto [x, y] : coords)
3170 {
3171
2/4
✓ Branch 0 taken 17812454 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17812454 times.
✗ Branch 3 not taken.
35624908 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3172
2/2
✓ Branch 0 taken 17600105 times.
✓ Branch 1 taken 212349 times.
17812454 if (rpos == rpos_t::None)
3173 212349 continue;
3174
3175
4/6
✓ Branch 0 taken 17600105 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17600105 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17600094 times.
35200210 if (MAPFFCOMBOFLAG(x, y) == flag)
3176 {
3177
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3178 11 break;
3179 }
3180
3181 17600094 bool seen = false;
3182
2/2
✓ Branch 0 taken 13509108 times.
✓ Branch 1 taken 22129546 times.
35638654 for (rpos_t r : rposes_seen)
3183 {
3184
2/2
✓ Branch 0 taken 18038560 times.
✓ Branch 1 taken 4090986 times.
22129546 if (r == rpos)
3185 {
3186 4090986 seen = true;
3187 4090986 break;
3188 }
3189 }
3190
2/2
✓ Branch 0 taken 13509108 times.
✓ Branch 1 taken 4090986 times.
17600094 if (seen)
3191 4090986 continue;
3192
3193
1/2
✓ Branch 0 taken 13509108 times.
✗ Branch 1 not taken.
13509108 rposes_seen.push_back(rpos);
3194
4/6
✓ Branch 0 taken 13509108 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13509108 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2386 times.
✓ Branch 5 taken 13506722 times.
27018216 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3195 {
3196
2/4
✓ Branch 0 taken 2386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2386 times.
✗ Branch 3 not taken.
4772 screen = get_screen_for_world_xy(x, y);
3197 2386 break;
3198 }
3199 }
3200
3201
3/4
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4452037 times.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
4454434 if (screen != -1) scr = get_scr(screen);
3202
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4452037 times.
4454434 if (!scr) return false;
3203
3204
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 439 times.
2397 if (trigger_rpos == rpos_t::None)
3205 {
3206 1958 checktrigger = true;
3207
1/2
✓ Branch 0 taken 1958 times.
✗ Branch 1 not taken.
1958 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3208 1958 }
3209 else
3210 {
3211 439 checktrigger = true;
3212
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3213 }
3214
3215
1/2
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
2397 sfx(scr->secretsfx);
3216
3217
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2391 times.
2397 if(scr->flags6&fTRIGGERFPERM)
3218 {
3219
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3220
3221
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3222 {
3223
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3224 3 setflag=false;
3225 3 }
3226
3227 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3228 // which case only the screen state for mSECRET may be set below.
3229
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3230 {
3231 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3232 }
3233 6 }
3234
3235
5/6
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1184 times.
2397 if (setflag && canPermSecret(cur_dmap, screen))
3236
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 463 times.
1905 if(!(scr->flags5&fTEMPSECRETS))
3237
1/2
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
721 setmapflag(scr, mSECRET);
3238
3239 2397 return true;
3240 4458043 }
3241
3242 14814242 void update_slopes()
3243 {
3244
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14814242 times.
14956598 for (auto& p : slopes)
3245 {
3246 142356 slope_object& s = p.second;
3247 142356 s.updateslope(); //sets old x/y poses
3248 }
3249 14814242 }
3250
3251 14407299 void update_freeform_combos()
3252 {
3253 14407299 ffscript_engine(false);
3254
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14383127 times.
14407299 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3255 {
3256 14383127 int wrap_right = world_w + 32;
3257 14383127 int wrap_bottom = world_h + 32;
3258
3259 485525545 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3260 471142418 mapscr* scr = ffc_handle.scr;
3261 471142418 ffcdata& thisffc = *ffc_handle.ffc;
3262
3263 // Combo 0?
3264
2/2
✓ Branch 0 taken 44992137 times.
✓ Branch 1 taken 426150281 times.
471142418 if(thisffc.data==0)
3265 426150281 return;
3266
3267 // Changer?
3268
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449108 times.
44992137 if(thisffc.flags&ffc_changer)
3269 543029 return;
3270
3271 // Stationary?
3272
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439264 times.
44449108 if(thisffc.flags&ffc_stationary)
3273 9844 return;
3274
3275 // Frozen because Hero's holding up an item?
3276
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44300982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439264 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3277 138282 return;
3278
3279 // Check for changers
3280
2/2
✓ Branch 0 taken 29543718 times.
✓ Branch 1 taken 14757264 times.
44300982 if (thisffc.link==0)
3281 {
3282 442453057 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3283
2/2
✓ Branch 0 taken 14755728 times.
✓ Branch 1 taken 412940065 times.
427695793 if (ffc_handle.id == other_ffc_handle.id)
3284 14755728 return true;
3285
3286 412940065 ffcdata& otherffc = *other_ffc_handle.ffc;
3287 // Combo 0?
3288
2/2
✓ Branch 0 taken 144689563 times.
✓ Branch 1 taken 268250502 times.
412940065 if(otherffc.data==0)
3289 268250502 return true;
3290
3291 // Not a changer?
3292
2/2
✓ Branch 0 taken 140701386 times.
✓ Branch 1 taken 3988177 times.
144689563 if(!(otherffc.flags&ffc_changer))
3293 140701386 return true;
3294
3295 // Ignore this changer?
3296
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3297 845836 return true;
3298
3299
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3300 ( // At exactly the same position,
3301
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3302
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3303 //or imprecision and close enough
3304
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3305 )
3306 && //and...
3307
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3308 {
3309 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3310 3562 return false;
3311 }
3312
3313 2721195 return true;
3314 426679695 });
3315 14757264 }
3316
3317
2/2
✓ Branch 0 taken 29543718 times.
✓ Branch 1 taken 14757264 times.
44300982 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3318
4/4
✓ Branch 0 taken 14757264 times.
✓ Branch 1 taken 29543718 times.
✓ Branch 2 taken 14679974 times.
✓ Branch 3 taken 14863744 times.
44300982 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3319 {
3320
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681135 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863744 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3321 {
3322 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3323 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3324 97278 thisffc.x += linked_ffc->vx;
3325 97278 thisffc.y += linked_ffc->vy;
3326 97278 }
3327 else
3328 {
3329 14766466 thisffc.prev_changer_x = thisffc.x.getZLong();
3330 14766466 thisffc.prev_changer_y = thisffc.y.getZLong();
3331 14766466 thisffc.x += thisffc.vx;
3332 14766466 thisffc.y += thisffc.vy;
3333 14766466 thisffc.vx += thisffc.ax;
3334 14766466 thisffc.vy += thisffc.ay;
3335
3336
3337
2/2
✓ Branch 0 taken 444012 times.
✓ Branch 1 taken 14322454 times.
14766466 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3338 {
3339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3340
3341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3342
3343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3344
3345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3346 14322454 }
3347 }
3348 14863744 }
3349 else
3350 {
3351
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437238 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3352 76129 thisffc.delay--;
3353 }
3354
3355 // Check if the FFC's off the side of the screen
3356
3357 // Left
3358
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930585 times.
14941034 if(thisffc.x<-32)
3359 {
3360
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3361 {
3362 253 thisffc.x = wrap_right+(thisffc.x+32);
3363 253 thisffc.solid_update(false);
3364 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3365 // Re-enable previous changer
3366 253 thisffc.changer_x = -1000;
3367 253 thisffc.changer_y = -1000;
3368 253 }
3369
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3370 {
3371 69 zc_ffc_set(thisffc, 0);
3372 69 thisffc.flags&=~ffc_carryover;
3373 69 }
3374 10449 }
3375 // Right
3376
2/2
✓ Branch 0 taken 14930404 times.
✓ Branch 1 taken 181 times.
14930585 else if(thisffc.x>=wrap_right)
3377 {
3378
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3379 {
3380 128 thisffc.x = thisffc.x-wrap_right-32;
3381 128 thisffc.solid_update(false);
3382 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3383 128 thisffc.changer_x = -1000;
3384 128 thisffc.changer_y = -1000;
3385 128 }
3386 else
3387 {
3388 53 zc_ffc_set(thisffc, 0);
3389 53 thisffc.flags&=~ffc_carryover;
3390 }
3391 181 }
3392
3393 // Top
3394
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915554 times.
14941034 if(thisffc.y<-32)
3395 {
3396
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3397 {
3398 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3399 8 thisffc.solid_update(false);
3400 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3401 8 thisffc.changer_x = -1000;
3402 8 thisffc.changer_y = -1000;
3403 8 }
3404
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3405 {
3406 317 zc_ffc_set(thisffc, 0);
3407 317 thisffc.flags&=~ffc_carryover;
3408 317 }
3409 25480 }
3410 // Bottom
3411
2/2
✓ Branch 0 taken 14914710 times.
✓ Branch 1 taken 844 times.
14915554 else if(thisffc.y>=wrap_bottom)
3412 {
3413
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3414 {
3415 753 thisffc.y = thisffc.y-wrap_bottom-32;
3416 753 thisffc.solid_update(false);
3417 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3418 753 thisffc.changer_x = -1000;
3419 753 thisffc.changer_y = -1000;
3420 753 }
3421 else
3422 {
3423 91 zc_ffc_set(thisffc, 0);
3424 91 thisffc.flags&=~ffc_carryover;
3425 }
3426 844 }
3427 14941034 thisffc.solid_update();
3428 441782470 });
3429 14383127 }
3430 14407299 }
3431
3432 2098420 bool hitcombo(int32_t x, int32_t y, int32_t combotype, byte layers)
3433 {
3434
2/2
✓ Branch 0 taken 14685796 times.
✓ Branch 1 taken 2097896 times.
16783692 for(int q = 0; q < 7; ++q)
3435 {
3436
2/2
✓ Branch 0 taken 12587376 times.
✓ Branch 1 taken 2098420 times.
14685796 if(layers&(1<<q)) //if layer is to be checked
3437
2/2
✓ Branch 0 taken 2097896 times.
✓ Branch 1 taken 524 times.
2098420 if(COMBOTYPE2(q-1,x,y)==combotype) //matching type
3438 524 return true;
3439 14685272 }
3440 2097896 return false;
3441 2098420 }
3442
3443 419684 int gethitcombo(int32_t x, int32_t y, int32_t combotype, byte layers)
3444 {
3445
2/2
✓ Branch 0 taken 2937788 times.
✓ Branch 1 taken 419684 times.
3357472 for(int q = 0; q < 7; ++q)
3446 {
3447
2/2
✓ Branch 0 taken 2518104 times.
✓ Branch 1 taken 419684 times.
2937788 if(layers&(1<<q)) //if layer is to be checked
3448
1/2
✓ Branch 0 taken 419684 times.
✗ Branch 1 not taken.
419684 if(COMBOTYPE2(q-1,x,y)==combotype) //matching type
3449 return MAPCOMBO2(q-1,x,y);
3450 2937788 }
3451 419684 return -1;
3452 419684 }
3453
3454 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3455 {
3456 for(int q = 0; q < 7; ++q)
3457 {
3458 if(layers&(1<<q)) //if layer is to be checked
3459 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3460 return true;
3461 }
3462 return false;
3463 }
3464
3465 231 optional<int> nextscr(int screen, int dir)
3466 {
3467 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3469 462 return (m<<7) + s;
3470 231 }
3471
3472 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3473 {
3474 1058 int32_t map = cur_map;
3475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : hero_screen;
3476 1058 return nextscr2(map, screen, dir);
3477 }
3478
3479 5576 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3480 {
3481 5576 screen = screen_index_direction(screen, (direction)dir);
3482
3483 // need to check for screens on other maps, 's' not valid, etc.
3484 5576 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3485
3486 // Fun fact: when a scrolling warp is triggered, this function
3487 // is never even called! - Saf
3488
2/2
✓ Branch 0 taken 3326 times.
✓ Branch 1 taken 2250 times.
6120 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3489 {
3490
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 545 times.
✓ Branch 4 taken 698 times.
2250 switch(dir)
3491 {
3492 case up:
3493
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3494
3495 83 break;
3496
3497 case down:
3498
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3499
3500 79 break;
3501
3502 case left:
3503
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 336 times.
545 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3504
3505 209 break;
3506
3507 case right:
3508
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 525 times.
698 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3509
3510 173 break;
3511 }
3512
3513 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3514 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3515 544 }
3516
3517 nowarp:
3518
4/4
✓ Branch 0 taken 5512 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5400 times.
5576 if(screen<0||screen>=128)
3519 176 return {-1, -1};
3520
3521 5400 return {map, screen};
3522 5576 }
3523
3524 403 optional<int> nextscr_mi(int mi, int dir)
3525 {
3526 403 int map = mi/MAPSCRSNORMAL;
3527 403 int screen = mi%MAPSCRSNORMAL;
3528 403 auto [m, s] = nextscr2(map, screen, dir);
3529
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3530 804 return (m<<7) + s;
3531 403 }
3532
3533 2115 void bombdoor(int32_t x,int32_t y)
3534 {
3535
2/2
✓ Branch 0 taken 2095 times.
✓ Branch 1 taken 20 times.
2115 if (!is_in_world_bounds(x, y))
3536 20 return;
3537
3538 2095 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3539 2095 mapscr* scr = rpos_handle.scr;
3540 2095 int screen = scr->screen;
3541 2903 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3542 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3543
3544
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2016 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2095 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3545 {
3546 69 scr->door[0]=dBOMBED;
3547 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3548 69 setmapflag(scr, mDOOR_UP);
3549 69 markBmap(-1, screen);
3550
3551
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3552 {
3553 69 setmapflag_mi(*v, mDOOR_DOWN);
3554 69 markBmap(-1,*v-(get_currdmap()<<7));
3555 69 }
3556 69 }
3557
3558
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2046 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2095 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3559 {
3560 39 scr->door[1]=dBOMBED;
3561 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3562 39 setmapflag(scr, mDOOR_DOWN);
3563 39 markBmap(-1, rpos_handle.screen);
3564
3565
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3566 {
3567 39 setmapflag_mi(*v, mDOOR_UP);
3568 39 markBmap(-1,*v-(get_currdmap()<<7));
3569 39 }
3570 39 }
3571
3572
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2028 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2095 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3573 {
3574 51 scr->door[2]=dBOMBED;
3575 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3576 51 setmapflag(scr, mDOOR_LEFT);
3577 51 markBmap(-1, rpos_handle.screen);
3578
3579
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3580 {
3581 51 setmapflag_mi(*v, mDOOR_RIGHT);
3582 51 markBmap(-1,*v-(get_currdmap()<<7));
3583 51 }
3584 51 }
3585
3586
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2009 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2095 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3587 {
3588 72 scr->door[3]=dBOMBED;
3589 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3590 72 setmapflag(scr, mDOOR_RIGHT);
3591 72 markBmap(-1, rpos_handle.screen);
3592
3593
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3594 {
3595 72 setmapflag_mi(*v, mDOOR_LEFT);
3596 72 markBmap(-1,*v-(get_currdmap()<<7));
3597 72 }
3598 72 }
3599 2115 }
3600
3601 6388109623 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3602 bool over, bool transp)
3603 {
3604 6388109623 auto& cmb = combobuf[cid];
3605
2/2
✓ Branch 0 taken 196956 times.
✓ Branch 1 taken 6387912667 times.
6388109623 if(cmb.animflags & AF_EDITOR_ONLY)
3606 196956 return;
3607
2/2
✓ Branch 0 taken 3312172969 times.
✓ Branch 1 taken 3075739698 times.
6387912667 if(over)
3608 {
3609
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3312172969 times.
3312172969 if(cmb.animflags & AF_TRANSPARENT)
3610 transp = !transp;
3611
2/2
✓ Branch 0 taken 319148412 times.
✓ Branch 1 taken 2993024557 times.
3312172969 if(transp)
3612 319148412 overcombotranslucent(dest, x, y, cid, cset, 128);
3613 2993024557 else overcombo(dest, x, y, cid, cset);
3614 3312172969 }
3615 3075739698 else putcombo(dest, x, y, cid, cset);
3616 6388109623 }
3617 6388118071 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3618 int32_t cset, byte layer, bool over, bool transp)
3619 {
3620
2/2
✓ Branch 0 taken 750943067 times.
✓ Branch 1 taken 5637175004 times.
6388118071 if (rpos != rpos_t::None)
3621 {
3622 5637175004 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3623
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 5636425480 times.
5637175004 if (plrpos != rpos_t::None)
3624 {
3625 5636425480 bool dosw = false;
3626
4/4
✓ Branch 0 taken 52860 times.
✓ Branch 1 taken 5636372620 times.
✓ Branch 2 taken 44412 times.
✓ Branch 3 taken 8448 times.
5636425480 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3627 {
3628
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3629 {
3630 draw_cmb(dest, x, y,
3631 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3632 }
3633 8448 dosw = true;
3634 8448 }
3635
4/4
✓ Branch 0 taken 31994243 times.
✓ Branch 1 taken 5604422789 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 31985795 times.
5636417032 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3636 {
3637 8448 dosw = true;
3638 8448 }
3639
2/2
✓ Branch 0 taken 5636408584 times.
✓ Branch 1 taken 16896 times.
5636425480 if (dosw)
3640 {
3641
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3642 {
3643 default: case swPOOF:
3644 break; //Nothing special here
3645 case swFLICKER:
3646 {
3647
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3648 8448 break; //Drawn this frame
3649 8448 return; //Not drawn this frame
3650 }
3651 case swRISE:
3652 {
3653 //Draw rising up
3654 y -= 8-(abs(Hero.switchhookclk-32)/4);
3655 break;
3656 }
3657 }
3658 8448 }
3659 5636417032 }
3660 5637166556 }
3661
3662 6388109623 draw_cmb(dest, x, y, cid, cset, over, transp);
3663 6388118071 }
3664
3665 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3666 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3667 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3668 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3669 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3670 //
3671 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3672 //
3673 // -16 < comboPositionX*16 + x < bitmapWidth
3674 // -16 < comboPositionY*16 + y < bitmapHeight
3675 //
3676 // The following start/end values are derived directly from the above.
3677 //
3678 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3679 39504800 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3680 {
3681 // if (bmp->clip)
3682 // {
3683 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3684 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3685 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3686 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3687 // return;
3688 // }
3689
3690
2/2
✓ Branch 0 taken 2171114 times.
✓ Branch 1 taken 37333686 times.
39504800 start_x = MAX(0, ceil((-15 - x) / 16.0));
3691
2/2
✓ Branch 0 taken 2180309 times.
✓ Branch 1 taken 37324491 times.
39504800 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3692
2/2
✓ Branch 0 taken 38115952 times.
✓ Branch 1 taken 1388848 times.
39504800 start_y = MAX(0, ceil((-15 - y) / 16.0));
3693
2/2
✓ Branch 0 taken 1678050 times.
✓ Branch 1 taken 37826750 times.
39504800 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3694 39504800 }
3695
3696 187019138 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3697 {
3698
1/2
✓ Branch 0 taken 187019138 times.
✗ Branch 1 not taken.
187019138 if(!show_ffcs) return;
3699 187019138 mapscr* scr = screen_handle.scr;
3700 187019138 mapscr* base_scr = screen_handle.base_scr;
3701
3702 187019138 y += playing_field_offset;
3703
3704 187019138 bool is_bg_layer = layer < -1;
3705
2/2
✓ Branch 0 taken 33937231 times.
✓ Branch 1 taken 153081907 times.
187019138 int real_layer = is_bg_layer ? abs(layer) : layer;
3706
2/2
✓ Branch 0 taken 187019138 times.
✓ Branch 1 taken 5581191346 times.
5768210484 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3707 {
3708
2/2
✓ Branch 0 taken 5375694046 times.
✓ Branch 1 taken 205497300 times.
5581191346 if (base_scr->ffcs[i].data == 0)
3709 5375694046 continue;
3710
4/4
✓ Branch 0 taken 37360890 times.
✓ Branch 1 taken 168136410 times.
✓ Branch 2 taken 18682926 times.
✓ Branch 3 taken 18677964 times.
205497300 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3711 18677964 continue;
3712
4/4
✓ Branch 0 taken 37360890 times.
✓ Branch 1 taken 149458446 times.
✓ Branch 2 taken 18682926 times.
✓ Branch 3 taken 18677964 times.
186819336 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3713 18677964 continue;
3714
4/4
✓ Branch 0 taken 149463408 times.
✓ Branch 1 taken 18677964 times.
✓ Branch 2 taken 18682926 times.
✓ Branch 3 taken 130780482 times.
168141372 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3715 130780482 continue;
3716
3717
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351920 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360890 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3718 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3719
3720 37358406 base_scr->ffcs[i].draw_ffc(bmp, x, y, (layer==-1));
3721 37358406 }
3722 187019138 }
3723 170989170 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3724 {
3725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170989170 times.
170989170 if(!show_ffcs) return;
3726 346556562 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3727 175567392 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3728 175567392 do_ffc_layer(bmp, layer, handle, 0, 0);
3729 175567392 });
3730 170989170 }
3731 74512829 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3732 {
3733 74512829 mapscr* scr = screen_handle.scr;
3734 74512829 mapscr* base_scr = screen_handle.base_scr;
3735
3736
4/4
✓ Branch 0 taken 60985709 times.
✓ Branch 1 taken 13527120 times.
✓ Branch 2 taken 13527120 times.
✓ Branch 3 taken 74512829 times.
74512829 if (type == -3 || type == -4)
3737 {
3738 27054240 y += playing_field_offset;
3739
3740
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
27054240 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3741 {
3742 if (base_scr->ffcs[i].data == 0)
3743 continue;
3744
3745 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3746 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3747
3748 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3749 }
3750 return;
3751 }
3752
3753 74512829 x -= viewport.x;
3754 74512829 y -= viewport.y - playing_field_offset;
3755
3756 74512829 bool over = true, transp = false;
3757 74512829 int layer = screen_handle.layer;
3758
3759
7/8
✓ Branch 0 taken 54029411 times.
✓ Branch 1 taken 20483418 times.
✓ Branch 2 taken 13154584 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33046517 times.
✓ Branch 5 taken 20982894 times.
✓ Branch 6 taken 3065892 times.
✓ Branch 7 taken 4262942 times.
74512829 switch(type ? type : layer)
3760 {
3761 case -2: //push blocks
3762
2/2
✓ Branch 0 taken 19519397 times.
✓ Branch 1 taken 13527120 times.
33046517 if (scr)
3763 {
3764
2/2
✓ Branch 0 taken 3435413872 times.
✓ Branch 1 taken 23171933 times.
3432150429 for(int32_t i=0; i<176; i++)
3765 {
3766 3435413872 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3767
3768
10/10
✓ Branch 0 taken 3435243528 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3433771556 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3433142573 times.
✓ Branch 5 taken 628983 times.
✓ Branch 6 taken 24420876 times.
✓ Branch 7 taken 3408721697 times.
✓ Branch 8 taken 42763031 times.
✓ Branch 9 taken 13948967 times.
3472461340 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3769
6/8
✓ Branch 0 taken 3430261043 times.
✓ Branch 1 taken 21539346 times.
✓ Branch 2 taken 3430261043 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3430261043 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3393213575 times.
3433142573 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3770 {
3771
4/4
✓ Branch 0 taken 4772508 times.
✓ Branch 1 taken 695982 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 4768851 times.
90994552 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3772 5468490 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3773 5468490 }
3774 3412631032 }
3775 23171933 }
3776 36699053 return;
3777
3778 case -1: //over combo
3779
1/2
✓ Branch 0 taken 20982894 times.
✗ Branch 1 not taken.
20982894 if (scr)
3780 {
3781
2/2
✓ Branch 0 taken 3692989344 times.
✓ Branch 1 taken 20982894 times.
3713972238 for(int32_t i=0; i<176; i++)
3782 {
3783
2/2
✓ Branch 0 taken 3673719196 times.
✓ Branch 1 taken 19270148 times.
3692989344 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3784 {
3785
4/4
✓ Branch 0 taken 15517569 times.
✓ Branch 1 taken 3752579 times.
✓ Branch 2 taken 22320 times.
✓ Branch 3 taken 15495249 times.
19270148 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3786 19270148 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3787 19270148 }
3788 3692989344 }
3789 20982894 }
3790 20982894 return;
3791
3792 case 1:
3793 case 4:
3794 case 5:
3795 case 6:
3796
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13154584 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13154584 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3797 {
3798
1/2
✓ Branch 0 taken 13154584 times.
✗ Branch 1 not taken.
13154584 if (scr)
3799 {
3800
2/2
✓ Branch 0 taken 11495373 times.
✓ Branch 1 taken 1659211 times.
13154584 if(base_scr->layeropacity[layer-1]!=255)
3801 1659211 transp = true;
3802 13154584 break;
3803 }
3804 }
3805 return;
3806
3807 case 2:
3808
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3065892 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3065892 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3809 {
3810
1/2
✓ Branch 0 taken 3065892 times.
✗ Branch 1 not taken.
3065892 if (scr)
3811 {
3812
2/2
✓ Branch 0 taken 2846295 times.
✓ Branch 1 taken 219597 times.
3065892 if(base_scr->layeropacity[layer-1]!=255)
3813 219597 transp = true;
3814
3815
2/2
✓ Branch 0 taken 2936982 times.
✓ Branch 1 taken 128910 times.
3065892 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3816 128910 over = false;
3817
3818 3065892 break;
3819 }
3820 }
3821 return;
3822
3823 case 3:
3824
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4262942 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4262942 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3825 {
3826
1/2
✓ Branch 0 taken 4262942 times.
✗ Branch 1 not taken.
4262942 if (scr)
3827 {
3828
2/2
✓ Branch 0 taken 4189229 times.
✓ Branch 1 taken 73713 times.
4262942 if(base_scr->layeropacity[layer-1]!=255)
3829 73713 transp = true;
3830
3831
2/2
✓ Branch 0 taken 36655 times.
✓ Branch 1 taken 60483 times.
4262942 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3832
2/2
✓ Branch 0 taken 97138 times.
✓ Branch 1 taken 4165804 times.
4262942 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3833 60483 over = false;
3834
3835 4262942 break;
3836 }
3837 }
3838 return;
3839 }
3840
3841 int start_x, end_x, start_y, end_y;
3842 20483418 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3843
2/2
✓ Branch 0 taken 20483418 times.
✓ Branch 1 taken 217187523 times.
237670941 for (int cy = start_y; cy < end_y; cy++)
3844 {
3845
2/2
✓ Branch 0 taken 3286665703 times.
✓ Branch 1 taken 217187523 times.
3503853226 for (int cx = start_x; cx < end_x; cx++)
3846 {
3847 3286665703 int i = cx + cy*16;
3848
4/4
✓ Branch 0 taken 2908327244 times.
✓ Branch 1 taken 378338459 times.
✓ Branch 2 taken 10227360 times.
✓ Branch 3 taken 2898099884 times.
3286665703 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3849 3286665703 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3850 3286665703 }
3851 217187523 }
3852 60985709 }
3853
3854 269079330 bool lenscheck(mapscr* scr, int layer)
3855 {
3856
4/4
✓ Branch 0 taken 268900382 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 269079330 times.
269079330 if(layer < 0 || layer > 6) return true;
3857
2/2
✓ Branch 0 taken 259580271 times.
✓ Branch 1 taken 9499059 times.
269079330 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3858 {
3859
2/2
✓ Branch 0 taken 209703781 times.
✓ Branch 1 taken 49876490 times.
259580271 if(!layer) return true;
3860
8/8
✓ Branch 0 taken 34921257 times.
✓ Branch 1 taken 174782524 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34662287 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34479509 times.
209703781 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3861 489872 return false;
3862 209262033 }
3863 else
3864 {
3865
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9499059 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9499059 times.
9499059 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3866 return false;
3867 }
3868 218761092 return true;
3869 268900382 }
3870
3871 156204473 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3872 {
3873 156204473 bool showlayer = true;
3874 156204473 mapscr* base_scr = screen_handle.base_scr;
3875 156204473 int layer = screen_handle.layer;
3876
2/2
✓ Branch 0 taken 42098741 times.
✓ Branch 1 taken 114105732 times.
156204473 int target = type ? type : layer;
3877
3/4
✓ Branch 0 taken 114105732 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20229305 times.
✓ Branch 3 taken 21869436 times.
156204473 switch(target)
3878 {
3879 case -2:
3880
1/2
✓ Branch 0 taken 20229305 times.
✗ Branch 1 not taken.
20229305 if(!show_layer_push)
3881 showlayer = false;
3882 20229305 break;
3883
3884 case -1:
3885
1/2
✓ Branch 0 taken 21869436 times.
✗ Branch 1 not taken.
21869436 if(!show_layer_over)
3886 showlayer = false;
3887 21869436 break;
3888
3889 case 1: case 2: case 3:
3890 case 4: case 5: case 6:
3891 114105732 showlayer = show_layers[target];
3892 114105732 break;
3893 }
3894
3895
2/2
✓ Branch 0 taken 42098741 times.
✓ Branch 1 taken 114105732 times.
156204473 if(!type)
3896 {
3897
2/2
✓ Branch 0 taken 113969534 times.
✓ Branch 1 taken 136198 times.
114105732 if(!lenscheck(base_scr,layer))
3898 136198 showlayer = false;
3899 114105732 }
3900
3901
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 156068275 times.
156204473 if(showlayer)
3902 {
3903
6/6
✓ Branch 0 taken 61041832 times.
✓ Branch 1 taken 95026443 times.
✓ Branch 2 taken 20539541 times.
✓ Branch 3 taken 40502291 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 20483418 times.
156068275 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3904 {
3905 60985709 do_scrolling_layer(bmp, type, screen_handle, x, y);
3906
4/4
✓ Branch 0 taken 20483418 times.
✓ Branch 1 taken 40502291 times.
✓ Branch 2 taken 19233766 times.
✓ Branch 3 taken 1249652 times.
60985709 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3907
2/2
✓ Branch 0 taken 1249076 times.
✓ Branch 1 taken 576 times.
1250228 if(mblock2.draw(bmp,layer))
3908 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3909 60985709 }
3910 156068275 }
3911 156204473 }
3912
3913 103055523 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3914 {
3915 103055523 bool showlayer = true;
3916
3917
2/4
✓ Branch 0 taken 103055523 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 103055523 times.
103055523 if(layer >= 0 && layer <= 6)
3918 {
3919 103055523 showlayer = show_layers[layer];
3920
3921
2/2
✓ Branch 0 taken 102928921 times.
✓ Branch 1 taken 126602 times.
103055523 if(!lenscheck(origin_scr,layer))
3922 126602 showlayer = false;
3923 103055523 }
3924
3925
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102928921 times.
103055523 if (showlayer)
3926 102928921 do_primitives(bmp, layer);
3927 103055523 }
3928
3929 // Called by do_walkflags
3930 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3931 {
3932 newcombo const &c = combobuf[cmbdat];
3933
3934 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3935
3936 int32_t xx = x-xofs;
3937 int32_t yy = y+playing_field_offset-yofs;
3938
3939 int32_t bridgedetected = 0;
3940
3941 for(int32_t i=0; i<4; i++)
3942 {
3943 int32_t tx=((i&2)<<2)+xx - viewport.x;
3944 int32_t ty=((i&1)<<3)+yy - viewport.y;
3945 int32_t tx2=((i&2)<<2)+x - viewport.x;
3946 int32_t ty2=((i&1)<<3)+y - viewport.y;
3947 for (int32_t j = lyr-1; j <= 1; j++)
3948 {
3949 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3950 {
3951 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3952 {
3953 bridgedetected |= (1<<i);
3954 }
3955 }
3956 else
3957 {
3958 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
3959 {
3960 bridgedetected |= (1<<i);
3961 }
3962 }
3963 }
3964 if ((bridgedetected & (1<<i)))
3965 {
3966 if (i >= 3) break;
3967 else continue;
3968 }
3969 bool doladdercheck = true;
3970
3971 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
3972 {
3973 for(int32_t k=0; k<8; k+=2)
3974 for(int32_t j=0; j<8; j+=2)
3975 if(((k+j)/2)%2)
3976 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
3977 }
3978 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
3979 {
3980 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
3981 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
3982 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
3983 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
3984 }
3985
3986 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
3987 {
3988 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
3989 {
3990 for(int32_t k=0; k<8; k+=2)
3991 for(int32_t j=0; j<8; j+=2)
3992 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
3993 }
3994 else
3995 {
3996 int32_t color = makecol(178,36,36);
3997
3998 if(isstepable(cmbdat)&& (!doladdercheck))
3999 color=makecol(165,105,8);
4000 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4001 color=makecol(170,170,170);
4002
4003 rectfill(dest,tx,ty,tx+7,ty+7,color);
4004 }
4005 }
4006 }
4007
4008 // Draw damage combos
4009 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4010 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4011 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4012
4013 if(dmg)
4014 {
4015 int32_t color = makecol(255,255,0);
4016 if (bridgedetected <= 0)
4017 {
4018 for(int32_t k=0; k<16; k+=2)
4019 for(int32_t j=0; j<16; j+=2)
4020 if(((k+j)/2)%2)
4021 {
4022 int32_t x0 = x - viewport.x;
4023 int32_t y0 = y - viewport.y;
4024 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4025 }
4026 }
4027 else
4028 {
4029 for(int32_t i=0; i<4; i++)
4030 {
4031 if (!(bridgedetected & (1<<i)))
4032 {
4033 int32_t tx=((i&2)<<2)+x - viewport.x;
4034 int32_t ty=((i&1)<<3)+y - viewport.y;
4035 for(int32_t k=0; k<8; k+=2)
4036 for(int32_t j=0; j<8; j+=2)
4037 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4038 }
4039 }
4040 }
4041 }
4042 }
4043 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4044 {
4045 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4046 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4047 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4048 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4049 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4050 newcombo const &c = combobuf[cmbdat];
4051
4052 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4053
4054 int32_t xx = x-viewport.x;
4055 int32_t yy = y+playing_field_offset-viewport.y;
4056
4057 int32_t bridgedetected = 0;
4058
4059 // Draw damage combos
4060 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4061
4062 for(int32_t i=0; i<4; i++)
4063 {
4064 int32_t tx=((i&2)<<2)+xx;
4065 int32_t ty=((i&1)<<3)+yy;
4066 int32_t tx2=((i&2)<<2)+x;
4067 int32_t ty2=((i&1)<<3)+y;
4068 for (int32_t m = lyr-1; m <= 1; m++)
4069 {
4070 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4071 {
4072 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4073 {
4074 bridgedetected |= (1<<i);
4075 }
4076 }
4077 else
4078 {
4079 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4080 {
4081 bridgedetected |= (1<<i);
4082 }
4083 }
4084 }
4085 if ((bridgedetected & (1<<i)))
4086 continue;
4087 bool doladdercheck = true;
4088
4089 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4090 {
4091 for(int32_t k=0; k<8; k+=2)
4092 for(int32_t j=0; j<8; j+=2)
4093 if(((k+j)/2)%2)
4094 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4095 }
4096 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4097 {
4098 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4099 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4100 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4101 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4102 }
4103
4104 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4105 {
4106 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4107 {
4108 for(int32_t k=0; k<8; k+=2)
4109 for(int32_t j=0; j<8; j+=2)
4110 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4111 }
4112 else
4113 {
4114 ALLEGRO_COLOR* color = &col_solid;
4115
4116 if(isstepable(cmbdat)&& (!doladdercheck))
4117 color=&col_stepable;
4118 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4119 color=&col_lhook;
4120
4121 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4122 }
4123 }
4124
4125 if(dmg)
4126 {
4127 for(int32_t k=0; k<8; k+=2)
4128 for(int32_t j=0; j<8; j+=2)
4129 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4130 }
4131 }
4132 }
4133
4134 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4135 {
4136 newcombo const &c = combobuf[cmbdat];
4137
4138 int32_t xx = x-xofs-viewport.x;
4139 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4140
4141 for(int32_t i=0; i<4; i++)
4142 {
4143 int32_t tx=((i&2)<<2)+xx;
4144 int32_t ty=((i&1)<<3)+yy;
4145
4146 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4147 {
4148 int32_t color = vc(10);
4149
4150 rectfill(dest,tx,ty,tx+7,ty+7,color);
4151 }
4152 }
4153 }
4154 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4155 {
4156 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4157 newcombo const &c = combobuf[cmbdat];
4158
4159 int32_t xx = x-viewport.x;
4160 int32_t yy = y+playing_field_offset-viewport.y;
4161
4162 for(int32_t i=0; i<4; i++)
4163 {
4164 int32_t tx=((i&2)<<2)+xx;
4165 int32_t ty=((i&1)<<3)+yy;
4166
4167 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4168 {
4169 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4170 }
4171 }
4172 }
4173
4174 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4175 {
4176 for(auto cx = 0; cx < 256; cx += 16)
4177 {
4178 for(auto cy = 0; cy < 176; cy += 16)
4179 {
4180 if(isSVLadder(cx,cy))
4181 {
4182 auto nx = cx+x, ny = cy+y;
4183 if(cy && !isSVLadder(cx,cy-16))
4184 line(dest,nx,ny,nx+15,ny,c);
4185 rectfill(dest,nx,ny,nx+3,ny+15,c);
4186 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4187 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4188 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4189 }
4190 else if(isSVPlatform(cx,cy))
4191 {
4192 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4193 }
4194 }
4195 }
4196 }
4197 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4198 {
4199 for(auto cx = 0; cx < 256; cx += 16)
4200 {
4201 for(auto cy = 0; cy < 176; cy += 16)
4202 {
4203 if(isSVLadder(cx,cy))
4204 {
4205 auto nx = cx+x, ny = cy+y;
4206 if(cy && !isSVLadder(cx,cy-16))
4207 al_draw_line(nx,ny,nx+15,ny,c,1);
4208 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4209 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4210 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4211 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4212 }
4213 else if(isSVPlatform(cx,cy))
4214 {
4215 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4216 }
4217 }
4218 }
4219 }
4220
4221 // Walkflags L4 cheat
4222 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4223 {
4224 if (!show_walkflags)
4225 return;
4226
4227 start_info_bmp();
4228
4229 mapscr* scr = screen_handles[0].scr;
4230 for(int32_t i=0; i<176; i++)
4231 {
4232 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4233 }
4234
4235 for(int32_t k=0; k<2; k++)
4236 {
4237 scr = screen_handles[k + 1].scr;
4238
4239 if (scr)
4240 {
4241 for(int32_t i=0; i<176; i++)
4242 {
4243 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4244 }
4245 }
4246 }
4247
4248 end_info_bmp();
4249 }
4250
4251 void do_walkflags(int32_t x, int32_t y)
4252 {
4253 if (!show_walkflags)
4254 return;
4255
4256 x += -viewport.x;
4257 y += playing_field_offset - viewport.y;
4258
4259 start_info_bmp();
4260
4261 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4262 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4263 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4264
4265 end_info_bmp();
4266 }
4267
4268 // Effectflags L4 cheat
4269 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4270 {
4271 if(show_effectflags)
4272 {
4273 start_info_bmp();
4274
4275 for(int32_t i=0; i<176; i++)
4276 {
4277 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4278 }
4279
4280 end_info_bmp();
4281 }
4282 }
4283
4284 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4285 {
4286 272141 int map = scr->map;
4287 272141 int screen = scr->screen;
4288
4289
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4290 {
4291 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4292
2/2
✓ Branch 0 taken 780869 times.
✓ Branch 1 taken 1124118 times.
1904987 if (!scr->is_valid()) continue;
4293
4294
2/2
✓ Branch 0 taken 137432944 times.
✓ Branch 1 taken 780869 times.
138213813 for(int32_t q = 0; q < 176; ++q)
4295 {
4296 137432944 newcombo const& cmb = combobuf[scr->data[q]];
4297
2/2
✓ Branch 0 taken 136828325 times.
✓ Branch 1 taken 604619 times.
137432944 if(cmb.type == cTORCH)
4298 {
4299 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4300 604619 }
4301 137432944 }
4302 780869 }
4303 272141 }
4304
4305 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4306 {
4307 272141 word c = scr->numFFC();
4308
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4309 {
4310 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4311
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4312 {
4313 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4314 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4315 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4316 14808 }
4317 537406 }
4318 272141 }
4319
4320 struct nearby_screen_t
4321 {
4322 int screen;
4323 int offx;
4324 int offy;
4325 screen_handles_t screen_handles;
4326 };
4327 typedef std::vector<nearby_screen_t> nearby_screens_t;
4328
4329 15492516 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4330 {
4331 15492516 nearby_screens_t nearby_screens;
4332
4333 15492516 mapscr* base_scr = origin_scr;
4334
1/2
✓ Branch 0 taken 15492516 times.
✗ Branch 1 not taken.
15492516 auto& nearby_screen = nearby_screens.emplace_back();
4335 15492516 nearby_screen.screen = cur_screen;
4336
1/2
✓ Branch 0 taken 15492516 times.
✗ Branch 1 not taken.
15492516 nearby_screen.screen_handles = create_screen_handles(base_scr);
4337
4338 15492516 return nearby_screens;
4339
1/2
✓ Branch 0 taken 15492516 times.
✗ Branch 1 not taken.
15492516 }
4340
4341 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4342 {
4343 48296 nearby_screens_t nearby_screens;
4344
4345
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4346
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4347
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4348
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4349
4350
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4351
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4352
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4353
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4354
4355
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4356 {
4357
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4358 {
4359 169672 int screen = cur_screen + x + y*16;
4360
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4361
4362
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4363
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4364
4365
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4366
4367
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4368 169672 nearby_screen.screen = screen;
4369 169672 nearby_screen.offx = offx;
4370 169672 nearby_screen.offy = offy;
4371
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4372 169672 }
4373 79928 }
4374
4375 48296 return nearby_screens;
4376
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4377
4378 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4379 {
4380 3658 nearby_screens_t nearby_screens;
4381
4382
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4383
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4384
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4385
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4386
4387
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4388
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4389
4390
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4391 {
4392
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4393 {
4394 18600 int screen = -1;
4395 mapscr* base_scr;
4396 int offx, offy;
4397
4398 18600 mapscr* maze_scr = maze_state.scr;
4399 18600 int maze_screen = maze_scr->screen;
4400
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4401
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4402 18600 int maze_screen_dx = x - maze_screen_x;
4403 18600 int maze_screen_dy = y - maze_screen_y;
4404 18600 int exitdir = maze_scr->exitdir;
4405
4406 bool should_draw_maze_screen;
4407
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4408 {
4409 9548 should_draw_maze_screen = true;
4410 9548 }
4411 else
4412 {
4413 9052 should_draw_maze_screen = true;
4414
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4415
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4416
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4417 }
4418
4419
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4420 {
4421 16048 screen = maze_state.scr->screen;
4422 16048 base_scr = maze_state.scr;
4423
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4424 16048 }
4425
4426
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4427 {
4428 2552 screen = cur_screen + x + y*16;
4429
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4430
4431
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4432
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4433
4434
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4435 2552 }
4436
4437
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4438 18600 nearby_screen.screen = screen;
4439 18600 nearby_screen.offx = offx;
4440 18600 nearby_screen.offy = offy;
4441
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4442 18600 }
4443 7308 }
4444
4445 3658 return nearby_screens;
4446
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4447
4448 15544470 static nearby_screens_t get_nearby_screens()
4449 {
4450
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15535256 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15544470 if (maze_state.active && maze_state.loopy)
4451 3658 return get_nearby_screens_smooth_maze();
4452
4453
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15492516 times.
15540812 if (is_in_scrolling_region())
4454 48296 return get_nearby_screens_scrolling_region();
4455
4456 15492516 return get_nearby_screens_non_scrolling_region();
4457 15544470 }
4458
4459 202094341 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4460 {
4461
2/2
✓ Branch 0 taken 203878943 times.
✓ Branch 1 taken 202094341 times.
405973284 for (auto& nearby_screen : nearby_screens)
4462 203878943 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4463 202094341 }
4464
4465 124355760 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4466 {
4467
2/2
✓ Branch 0 taken 15544470 times.
✓ Branch 1 taken 108811290 times.
124355760 if(layer != msgstr_layer) return;
4468
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 if(!dest) dest = framebuf;
4469
4470
2/2
✓ Branch 0 taken 679732 times.
✓ Branch 1 taken 14864738 times.
15544470 if(!(msg_bg_display_buf->clip))
4471 {
4472 679732 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4473 679732 }
4474
4475
2/2
✓ Branch 0 taken 679732 times.
✓ Branch 1 taken 14864738 times.
15544470 if(!(msg_portrait_display_buf->clip))
4476 {
4477 679732 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4478 679732 }
4479
4480
2/2
✓ Branch 0 taken 693139 times.
✓ Branch 1 taken 14851331 times.
15544470 if(!(msg_txt_display_buf->clip))
4481 {
4482 693139 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4483 693139 }
4484 124355760 }
4485
4486 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4487
4488 62177880 static void set_draw_screen_clip(BITMAP* bmp)
4489 {
4490 62177880 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4491 62177880 }
4492
4493 46131730 void draw_screen(bool showhero, bool runGeneric)
4494 {
4495 46131730 clear_info_bmp();
4496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46131730 times.
46131730 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4497 {
4498 FFCore.doScriptMenuDraws();
4499 return;
4500 }
4501
4502
2/2
✓ Branch 0 taken 31188404 times.
✓ Branch 1 taken 14943326 times.
46131730 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4503
4504 46131730 clear_bitmap(framebuf);
4505 46131730 clear_clip_rect(framebuf);
4506
4507 46131730 int32_t cmby2=0;
4508
4509 // Draw some background layers
4510 46131730 clear_bitmap(scrollbuf);
4511
4512 46131730 auto nearby_screens = get_nearby_screens();
4513
4514 // Handle layer 2/3 possibly being background layers.
4515
1/2
✓ Branch 0 taken 46131730 times.
✗ Branch 1 not taken.
61812518 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4516 15680788 mapscr* base_scr = screen_handles[0].base_scr;
4517
2/2
✓ Branch 0 taken 15553506 times.
✓ Branch 1 taken 127282 times.
15680788 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4518 127282 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4519 15680788 });
4520
4521
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 46004448 times.
46131730 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4522 {
4523
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 do_layer_primitives(scrollbuf, 2);
4524
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 particles.draw(scrollbuf, true, 2);
4525 127282 }
4526
2/2
✓ Branch 0 taken 15544470 times.
✓ Branch 1 taken 30587260 times.
46131730 _do_current_ffc_layer(scrollbuf, -2);
4527
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15417188 times.
15544470 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4528
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 draw_msgstr(2, scrollbuf);
4529
4530
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4531 15680788 mapscr* base_scr = screen_handles[0].base_scr;
4532
2/2
✓ Branch 0 taken 15588128 times.
✓ Branch 1 taken 92660 times.
15680788 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4533 92660 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4534 15680788 });
4535
4536
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15451810 times.
15544470 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4537 {
4538
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 do_layer_primitives(scrollbuf, 3);
4539
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 particles.draw(scrollbuf, true, 3);
4540 92660 }
4541
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(scrollbuf, -3);
4542
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15451810 times.
15544470 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4543
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 draw_msgstr(3, scrollbuf);
4544
4545 // Draw the main combo screens ("layer 0").
4546
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4547 15680788 mapscr* base_scr = screen_handles[0].base_scr;
4548
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15680788 times.
15680788 if (lenscheck(base_scr, 0))
4549 {
4550 15680788 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4551 15680788 }
4552 15680788 });
4553
4554
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15544470 times.
15544470 if (lenscheck(hero_scr, 0))
4555 {
4556
2/2
✓ Branch 0 taken 471311 times.
✓ Branch 1 taken 15073159 times.
15544470 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4557
3/4
✓ Branch 0 taken 471311 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 467175 times.
475447 if(mblock2.draw(scrollbuf,0))
4558
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4559 15544470 }
4560
4561 // Lens hints, then primitives, then particles.
4562
6/10
✓ Branch 0 taken 15534441 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15534441 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15534441 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15544470 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4563 {
4564
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4565
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4566 5876 }
4567
4568
2/4
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15544470 times.
✗ Branch 3 not taken.
15544470 if(show_layers[0] && lenscheck(hero_scr,0))
4569
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_primitives(scrollbuf, 0);
4570
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 particles.draw(scrollbuf, true, 0);
4571
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(scrollbuf, 0);
4572
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 draw_msgstr(0, scrollbuf);
4573
4574
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 set_draw_screen_clip(scrollbuf);
4575
4576
2/2
✓ Branch 0 taken 15201211 times.
✓ Branch 1 taken 343259 times.
15544470 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4577 {
4578
4/4
✓ Branch 0 taken 15199337 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 15110953 times.
30365796 if(showhero &&
4579
4/6
✓ Branch 0 taken 15199337 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15164585 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 15164585 times.
✗ Branch 5 not taken.
15199337 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4580 {
4581
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4582 {
4583 34752 cmby2=16;
4584 34752 }
4585
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4586 {
4587 53632 cmby2=-16;
4588 53632 }
4589
4590
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4591
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4592
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4593
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4594
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4595
4596
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4597
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4598
4599
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4600 {
4601
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4602
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4603 15232 }
4604 88384 }
4605 15201211 }
4606
4607
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4608 15680788 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4609 15680788 });
4610
4611
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_layer_primitives(scrollbuf, 1);
4612
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 particles.draw(scrollbuf, true, 1);
4613
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(scrollbuf, 1);
4614
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 draw_msgstr(1, scrollbuf);
4615
4616 // Handle layer 2 NOT being used as background layers.
4617
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4618 15680788 mapscr* base_scr = screen_handles[0].base_scr;
4619
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15553506 times.
15680788 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4620 15553506 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4621 15680788 });
4622
4623
2/2
✓ Branch 0 taken 15417188 times.
✓ Branch 1 taken 127282 times.
15544470 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4624 {
4625
1/2
✓ Branch 0 taken 15417188 times.
✗ Branch 1 not taken.
15417188 do_layer_primitives(scrollbuf, 2);
4626
1/2
✓ Branch 0 taken 15417188 times.
✗ Branch 1 not taken.
15417188 particles.draw(scrollbuf, true, 2);
4627 15417188 }
4628
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(scrollbuf, 2);
4629
2/2
✓ Branch 0 taken 15417188 times.
✓ Branch 1 taken 127282 times.
15544470 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4630
1/2
✓ Branch 0 taken 15417188 times.
✗ Branch 1 not taken.
15417188 draw_msgstr(2, scrollbuf);
4631
4632
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4633
4634
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15201211 times.
15544470 if(get_qr(qr_LAYER12UNDERCAVE))
4635 {
4636
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
686518 if(showhero &&
4637
3/6
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343259 times.
✗ Branch 5 not taken.
343259 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4638 {
4639 if(Hero.getAction()==climbcovertop)
4640 {
4641 cmby2=16;
4642 }
4643 else if(Hero.getAction()==climbcoverbottom)
4644 {
4645 cmby2=-16;
4646 }
4647
4648 decorations.draw2(scrollbuf,true);
4649 Hero.draw(scrollbuf);
4650 decorations.draw(scrollbuf,true);
4651 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4652 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4653
4654 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4655 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4656
4657 if(int32_t(Hero.getX())&15)
4658 {
4659 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4660 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4661 }
4662 }
4663 343259 }
4664
4665
2/2
✓ Branch 0 taken 471311 times.
✓ Branch 1 taken 15073159 times.
15544470 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4666 {
4667
1/2
✓ Branch 0 taken 15073159 times.
✗ Branch 1 not taken.
30282636 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4668 15209477 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4669
2/2
✓ Branch 0 taken 14478921 times.
✓ Branch 1 taken 730556 times.
15209477 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4670 {
4671 730556 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4672 730556 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4673 730556 }
4674 15209477 });
4675
4676
1/2
✓ Branch 0 taken 15073159 times.
✗ Branch 1 not taken.
15073159 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4677 15073159 }
4678
4679 // Show walkflags cheat
4680
2/4
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15544470 times.
15544470 if (show_walkflags || show_effectflags)
4681 {
4682 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4683 do_walkflags(screen_handles, offx, offy);
4684 do_effectflags(screen_handles[0].base_scr, offx, offy);
4685 });
4686
4687 do_walkflags(0, 0);
4688 }
4689
4690
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4691
4692 // Lens hints, doors etc.
4693
4/8
✓ Branch 0 taken 15534441 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15534441 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15534441 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15544470 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4694 {
4695
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4696 {
4697
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4698
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4699 4153 }
4700
4701
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4702
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4703 10029 }
4704
4705 // Blit those layers onto framebuf
4706
4707
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 set_draw_screen_clip(framebuf);
4708
4709
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4710
4711 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4712 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4713
4714 // Draw the subscreen, without clipping
4715
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6293086 times.
15544470 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4716 {
4717 9251384 bool dotime = false;
4718
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4719
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4720 9251384 }
4721
4722 // Draw some sprites onto framebuf
4723
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 set_clip_rect(framebuf,0,0,256,232);
4724
4725
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15444974 times.
15544470 if(!(pricesdisplaybuf->clip))
4726 {
4727
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4728 99496 }
4729
4730
5/6
✓ Branch 0 taken 15498844 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15492516 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15544470 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4731 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4732
4733
8/10
✓ Branch 0 taken 15542596 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15542596 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15507844 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15507844 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15454212 times.
✓ Branch 9 taken 53632 times.
15544470 if(showhero && ((Hero.getAction()!=climbcovertop)&&(Hero.getAction()!=climbcoverbottom)))
4734 {
4735
1/2
✓ Branch 0 taken 15454212 times.
✗ Branch 1 not taken.
15454212 Hero.draw_under(framebuf);
4736
4737
3/4
✓ Branch 0 taken 15454212 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15312827 times.
15454212 if(Hero.isSwimming())
4738 {
4739
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(framebuf,true);
4740
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(framebuf);
4741
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(framebuf,true);
4742 141385 }
4743 15454212 }
4744
4745
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 15518375 times.
15544470 if(drawguys)
4746 {
4747
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 13535701 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
15518375 if(get_qr(qr_NOFLICKER) || (frame&1))
4748 {
4749 // Just clips sprites if in a repeating, smooth maze.
4750
2/2
✓ Branch 0 taken 14517576 times.
✓ Branch 1 taken 9214 times.
14526790 bool do_clip = maze_state.active && maze_state.loopy;
4751
4752
3/4
✓ Branch 0 taken 23639222 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9112432 times.
✓ Branch 3 taken 14526790 times.
23639222 for(int32_t i=0; i<Ewpns.Count(); i++)
4753 {
4754
3/4
✓ Branch 0 taken 9112432 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8914489 times.
9112432 if(((weapon *)Ewpns.spr(i))->behind)
4755
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4756 9112432 }
4757
1/2
✓ Branch 0 taken 14526790 times.
✗ Branch 1 not taken.
14526790 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4758
4759
3/4
✓ Branch 0 taken 19201917 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675127 times.
✓ Branch 3 taken 14526790 times.
19201917 for(int32_t i=0; i<Lwpns.Count(); i++)
4760 {
4761
3/4
✓ Branch 0 taken 4675127 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4671922 times.
4675127 if(((weapon *)Lwpns.spr(i))->behind)
4762
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4763 4675127 }
4764
1/2
✓ Branch 0 taken 14526790 times.
✗ Branch 1 not taken.
14526790 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4765
4766
6/6
✓ Branch 0 taken 9789926 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8441626 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14526790 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4767 {
4768
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9111979 times.
9115637 if (do_clip)
4769
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4770 else
4771
1/2
✓ Branch 0 taken 9111979 times.
✗ Branch 1 not taken.
9111979 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4772 9115637 }
4773
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14523132 times.
14526790 if (do_clip)
4774
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4775 else
4776
1/2
✓ Branch 0 taken 14523132 times.
✗ Branch 1 not taken.
14523132 guys.draw(framebuf,true);
4777
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14523132 times.
14526790 if (do_clip)
4778 {
4779 3658 int maze_screen = maze_state.scr->screen;
4780
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4781
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4782 3658 }
4783
1/2
✓ Branch 0 taken 14526790 times.
✗ Branch 1 not taken.
14526790 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4784
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14523132 times.
14526790 if (do_clip)
4785
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4786
4787
1/2
✓ Branch 0 taken 14526790 times.
✗ Branch 1 not taken.
14526790 chainlinks.draw(framebuf,true);
4788
1/2
✓ Branch 0 taken 14526790 times.
✗ Branch 1 not taken.
14526790 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4789 //Lwpns.draw(framebuf,true);
4790
4791
3/4
✓ Branch 0 taken 23639222 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9112432 times.
✓ Branch 3 taken 14526790 times.
23639222 for(int32_t i=0; i<Ewpns.Count(); i++)
4792 {
4793
3/4
✓ Branch 0 taken 9112432 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8914489 times.
✓ Branch 3 taken 197943 times.
9112432 if(!((weapon *)Ewpns.spr(i))->behind)
4794
2/4
✓ Branch 0 taken 8914489 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8914489 times.
✗ Branch 3 not taken.
8914489 Ewpns.spr(i)->draw(framebuf);
4795 9112432 }
4796
1/2
✓ Branch 0 taken 14526790 times.
✗ Branch 1 not taken.
14526790 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4797
4798
3/4
✓ Branch 0 taken 19201917 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675127 times.
✓ Branch 3 taken 14526790 times.
19201917 for(int32_t i=0; i<Lwpns.Count(); i++)
4799 {
4800
3/4
✓ Branch 0 taken 4675127 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671922 times.
✓ Branch 3 taken 3205 times.
4675127 if(!((weapon *)Lwpns.spr(i))->behind)
4801
2/4
✓ Branch 0 taken 4671922 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671922 times.
✗ Branch 3 not taken.
4671922 Lwpns.spr(i)->draw(framebuf);
4802 4675127 }
4803
1/2
✓ Branch 0 taken 14526790 times.
✗ Branch 1 not taken.
14526790 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4804
4805
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14523132 times.
14526790 if (do_clip)
4806
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4807 else
4808
1/2
✓ Branch 0 taken 14523132 times.
✗ Branch 1 not taken.
14523132 items.draw(framebuf,true);
4809
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14523132 times.
14526790 if (do_clip)
4810 {
4811 3658 int maze_screen = maze_state.scr->screen;
4812
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4813
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4814 3658 }
4815
1/2
✓ Branch 0 taken 14526790 times.
✗ Branch 1 not taken.
14526790 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4816
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14523132 times.
14526790 if (do_clip)
4817
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4818 14526790 }
4819 else
4820 {
4821
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4822 {
4823
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
4824
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
4825 505372 }
4826
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4827
4828
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4829 {
4830
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
4831 Lwpns.spr(i)->draw(framebuf);
4832 231146 }
4833
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4834
4835
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4836 {
4837
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4838 228620 }
4839
4840
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(framebuf,false);
4841
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4842
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(framebuf,false);
4843
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4844 //Lwpns.draw(framebuf,false);
4845
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(framebuf,false);
4846
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4847
4848
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4849 {
4850
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
4851 {
4852
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
4853 496727 }
4854 505372 }
4855
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4856
4857
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4858 {
4859
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
4860 {
4861
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(framebuf);
4862 231146 }
4863 231146 }
4864
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4865 }
4866
4867
1/2
✓ Branch 0 taken 15518375 times.
✗ Branch 1 not taken.
15518375 guys.draw2(framebuf,true);
4868 15518375 }
4869
4870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15544470 times.
15544470 if(mirror_portal.destdmap > -1)
4871 mirror_portal.draw(framebuf);
4872
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 portals.draw(framebuf,true);
4873
4874
8/10
✓ Branch 0 taken 15542596 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15542596 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15507844 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15507844 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15454212 times.
✓ Branch 9 taken 53632 times.
15544470 if(showhero && ((Hero.getAction()!=climbcovertop)&& (Hero.getAction()!=climbcoverbottom)))
4875 {
4876
2/2
✓ Branch 0 taken 14989317 times.
✓ Branch 1 taken 464895 times.
15454212 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4877 {
4878
1/2
✓ Branch 0 taken 14989317 times.
✗ Branch 1 not taken.
14989317 mblock2.draw(framebuf,-1);
4879
1/2
✓ Branch 0 taken 14989317 times.
✗ Branch 1 not taken.
14989317 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
4880 14989317 }
4881
3/4
✓ Branch 0 taken 15454212 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15312827 times.
✓ Branch 3 taken 141385 times.
15454212 if(!Hero.isSwimming())
4882 {
4883
8/12
✓ Branch 0 taken 15312827 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15312827 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15292945 times.
✓ Branch 5 taken 19882 times.
✓ Branch 6 taken 15292945 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15292945 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15311457 times.
15312827 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4884 {
4885
2/2
✓ Branch 0 taken 19197 times.
✓ Branch 1 taken 15293630 times.
15312827 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4886 19197 }
4887
4888
6/8
✓ Branch 0 taken 15312827 times.
✓ Branch 1 taken 15293630 times.
✓ Branch 2 taken 15312827 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15312827 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15298406 times.
✓ Branch 7 taken 14421 times.
19197 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
4889 {
4890
1/2
✓ Branch 0 taken 15298406 times.
✗ Branch 1 not taken.
15298406 decorations.draw2(framebuf,true);
4891
1/2
✓ Branch 0 taken 15298406 times.
✗ Branch 1 not taken.
15298406 Hero.draw(framebuf);
4892
1/2
✓ Branch 0 taken 15298406 times.
✗ Branch 1 not taken.
15298406 decorations.draw(framebuf,true);
4893 15298406 }
4894 15312827 }
4895 15454212 }
4896
4897
3/4
✓ Branch 0 taken 54885962 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39341492 times.
✓ Branch 3 taken 15544470 times.
54885962 for(int32_t i=0; i<guys.Count(); i++)
4898 {
4899
3/4
✓ Branch 0 taken 39341492 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15946503 times.
✓ Branch 3 taken 23394989 times.
39341492 if(((enemy*)guys.spr(i))->family == eeWALK)
4900 {
4901
3/4
✓ Branch 0 taken 15946503 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15939208 times.
15946503 if(((eStalfos*)guys.spr(i))->hashero)
4902 {
4903
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
4904 7295 }
4905 15946503 }
4906
4907
3/4
✓ Branch 0 taken 39341492 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 38834330 times.
39341492 if(((enemy*)guys.spr(i))->family == eeWALLM)
4908 {
4909
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
4910 {
4911
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
4912 1329 }
4913 507162 }
4914
4915
11/20
✓ Branch 0 taken 39341492 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39341492 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39341492 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39341492 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39341492 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39341492 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39341492 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39341492 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39341492 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37998798 times.
39341492 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
4916 {
4917 //Jumping enemies in front of Hero.
4918
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
4919 1342694 }
4920
1/2
✓ Branch 0 taken 39341492 times.
✗ Branch 1 not taken.
39341492 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
4921 39341492 }
4922
4923 // Draw some layers onto framebuf
4924
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 set_draw_screen_clip(framebuf);
4925
5/6
✓ Branch 0 taken 15498844 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15492516 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15544470 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4926 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4927
4928 // Handle layer 3 NOT being used as background layers.
4929
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4930 15680788 mapscr* base_scr = screen_handles[0].base_scr;
4931
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15588128 times.
15680788 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4932 15588128 do_layer(framebuf, 0, screen_handles[3], offx, offy);
4933 15680788 });
4934
4935
2/2
✓ Branch 0 taken 15451810 times.
✓ Branch 1 taken 92660 times.
15544470 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4936 {
4937
1/2
✓ Branch 0 taken 15451810 times.
✗ Branch 1 not taken.
15451810 do_layer_primitives(framebuf, 3);
4938
1/2
✓ Branch 0 taken 15451810 times.
✗ Branch 1 not taken.
15451810 particles.draw(framebuf, true, 3);
4939 15451810 }
4940
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(framebuf, 3);
4941
2/2
✓ Branch 0 taken 15451810 times.
✓ Branch 1 taken 92660 times.
15544470 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4942
1/2
✓ Branch 0 taken 15451810 times.
✗ Branch 1 not taken.
15451810 draw_msgstr(3);
4943
4944
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4945 15680788 do_layer(framebuf, 0, screen_handles[4], offx, offy);
4946 15680788 });
4947
4948
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_layer_primitives(framebuf, 4);
4949
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 particles.draw(framebuf, true, 4);
4950
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(framebuf, 4);
4951
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 draw_msgstr(4);
4952
4953
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4954 15680788 do_layer(framebuf, -1, screen_handles[0], offx, offy);
4955
2/2
✓ Branch 0 taken 14400201 times.
✓ Branch 1 taken 1280587 times.
15680788 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
4956 {
4957 1280587 do_layer(framebuf, -1, screen_handles[1], offx, offy);
4958 1280587 do_layer(framebuf, -1, screen_handles[2], offx, offy);
4959 1280587 }
4960 15680788 });
4961
4962
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
4963
4964 // Draw some flying sprites onto framebuf
4965
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 clear_clip_rect(framebuf);
4966
5/6
✓ Branch 0 taken 15498844 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15492516 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15544470 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4967 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4968
4969 //Jumping Hero and jumping enemies are drawn on this layer.
4970
5/8
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15544470 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15544470 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14421 times.
✓ Branch 7 taken 15530049 times.
15544470 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
4971 {
4972
1/2
✓ Branch 0 taken 14421 times.
✗ Branch 1 not taken.
14421 decorations.draw2(framebuf,false);
4973
1/2
✓ Branch 0 taken 14421 times.
✗ Branch 1 not taken.
14421 Hero.draw(framebuf);
4974
1/2
✓ Branch 0 taken 14421 times.
✗ Branch 1 not taken.
14421 chainlinks.draw(framebuf,true);
4975
1/2
✓ Branch 0 taken 14421 times.
✗ Branch 1 not taken.
14421 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4976
4977
3/4
✓ Branch 0 taken 17163 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14421 times.
17163 for(int32_t i=0; i<Lwpns.Count(); i++)
4978 {
4979
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
4980 {
4981
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
4982 239 }
4983 2742 }
4984
1/2
✓ Branch 0 taken 14421 times.
✗ Branch 1 not taken.
14421 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
4985
4986
1/2
✓ Branch 0 taken 14421 times.
✗ Branch 1 not taken.
14421 decorations.draw(framebuf,false);
4987 14421 }
4988
4989
5/6
✓ Branch 0 taken 3288982 times.
✓ Branch 1 taken 12255488 times.
✓ Branch 2 taken 44340118 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32084630 times.
✓ Branch 5 taken 12255488 times.
47629100 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
4990 {
4991
13/22
✓ Branch 0 taken 32084630 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32084630 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27178532 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27178532 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27178532 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27178532 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27178532 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27178532 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27178532 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27178532 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27171964 times.
32084630 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
4992 {
4993
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(framebuf);
4994 4912666 }
4995 44340118 }
4996 else
4997 {
4998
3/4
✓ Branch 0 taken 10545844 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288982 times.
10545844 for(int32_t i=0; i<guys.Count(); i++)
4999 {
5000
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5001 {
5002
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
5003 1662516 }
5004 7256862 }
5005 }
5006
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
5007
5008 // Draw the Moving Fairy above layer 3
5009
3/4
✓ Branch 0 taken 18691607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3147137 times.
✓ Branch 3 taken 15544470 times.
18691607 for(int32_t i=0; i<items.Count(); i++)
5010
6/8
✓ Branch 0 taken 3147137 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69867 times.
✓ Branch 3 taken 3077270 times.
✓ Branch 4 taken 69867 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60153 times.
✓ Branch 7 taken 9714 times.
3207290 if(itemsbuf[items.spr(i)->id].family == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5011
2/4
✓ Branch 0 taken 60153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60153 times.
✗ Branch 3 not taken.
60153 items.spr(i)->draw(framebuf);
5012
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
5013
5014 // Draw some layers onto framebuf
5015
5016
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 set_draw_screen_clip(framebuf);
5017
5018
2/2
✓ Branch 0 taken 15530118 times.
✓ Branch 1 taken 14352 times.
15544470 if (lightbeam_present)
5019 {
5020 14352 color_map = &trans_table2;
5021
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5022
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
5023 else
5024
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
5025 14352 color_map = &trans_table;
5026 14352 }
5027
5028
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5029 15680788 do_layer(framebuf, 0, screen_handles[5], offx, offy);
5030 15680788 });
5031
5032
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_layer_primitives(framebuf, 5);
5033
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 particles.draw(framebuf, true, 5);
5034
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(framebuf, 5);
5035
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 draw_msgstr(5);
5036
5037
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(framebuf, -1); // 'overhead' freeform combos
5038
5039
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
5040
5041
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5042 15680788 do_layer(framebuf, 0, screen_handles[6], offx, offy);
5043 15680788 });
5044
5045
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 do_layer_primitives(framebuf, 6);
5046
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 particles.draw(framebuf, true, 6);
5047
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(framebuf, 6);
5048
5049 15544470 bool any_dark = false;
5050
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5051 15680788 mapscr* base_scr = screen_handles[0].scr;
5052 15680788 any_dark |= is_dark(base_scr);
5053 15680788 });
5054
5055 // Handle low drawn darkness
5056
4/4
✓ Branch 0 taken 1274251 times.
✓ Branch 1 taken 14270219 times.
✓ Branch 2 taken 1030480 times.
✓ Branch 3 taken 243771 times.
15544470 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5057 {
5058
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5059 250005 mapscr* base_scr = screen_handles[0].scr;
5060 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5061 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5062 250005 });
5063
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
5064
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
5065
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243771 times.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5066 250005 mapscr* base_scr = screen_handles[0].scr;
5067
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
5068 {
5069 4730 offy += playing_field_offset;
5070 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5071 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5072 4730 }
5073 250005 });
5074 243771 }
5075
5076 //Darkroom if under the subscreen
5077
6/6
✓ Branch 0 taken 1274251 times.
✓ Branch 1 taken 14270219 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 450967 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15544470 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5078 {
5079
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5080
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5082 {
5083 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5084 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5085 }
5086
5087 231780 color_map = &trans_table2;
5088
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5089 {
5090
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5091
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5092
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5093 144 }
5094 else
5095 {
5096
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5097
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5098 }
5099 231780 color_map = &trans_table;
5100
5101
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5102
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5103 231780 }
5104
5105
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15498844 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15544470 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5106 {
5107 draw_lens_over();
5108 --lensclk;
5109 }
5110
5111 // Draw some text on framebuf
5112
5113
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 set_clip_rect(framebuf,0,0,256,232);
5114
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5115
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 draw_msgstr(6);
5116
5117 // Draw the subscreen, without clipping
5118
2/2
✓ Branch 0 taken 6293086 times.
✓ Branch 1 taken 9251384 times.
15544470 if(get_qr(qr_SUBSCREENOVERSPRITES))
5119 {
5120
2/4
✓ Branch 0 taken 6293086 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6293086 times.
✗ Branch 3 not taken.
6293086 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5121
5122 // Draw primitives over subscren
5123
1/2
✓ Branch 0 taken 6293086 times.
✗ Branch 1 not taken.
6293086 do_primitives(framebuf, 7); //Layer '7' appears above subscreen if quest rule is set
5124 6293086 }
5125
5126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15544470 times.
15544470 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5127 draw_msgstr(6);
5128
5129 // Handle high-drawn darkness
5130
6/6
✓ Branch 0 taken 1274251 times.
✓ Branch 1 taken 14270219 times.
✓ Branch 2 taken 450967 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 438976 times.
15544470 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5131 {
5132
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5133
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5135 {
5136 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5137 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5138 }
5139
5140 11991 color_map = &trans_table2;
5141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5142 {
5143 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5145 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5146 }
5147 else
5148 {
5149
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5150
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5151 }
5152 11991 color_map = &trans_table;
5153
5154
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5155
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5156 11991 }
5157
5158
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 _do_current_ffc_layer(framebuf, 7);
5159
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 draw_msgstr(7);
5160
5161
1/2
✓ Branch 0 taken 15544470 times.
✗ Branch 1 not taken.
15544470 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5162
3/4
✓ Branch 0 taken 14943326 times.
✓ Branch 1 taken 601144 times.
✓ Branch 2 taken 14943326 times.
✗ Branch 3 not taken.
15544470 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5163 76718990 }
5164
5165 // TODO: separate setting door data and drawing door
5166 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5167 {
5168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5169
5170 28153 int32_t d=scr->door_combo_set;
5171
5172
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5173 {
5174 case dt_wall:
5175 case dt_walk:
5176 if(!even_walls)
5177 break;
5178 [[fallthrough]];
5179 case dt_pass:
5180
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5181 1036 break;
5182 [[fallthrough]];
5183 case dt_lock:
5184 case dt_shut:
5185 case dt_boss:
5186 case dt_olck:
5187 case dt_osht:
5188 case dt_obos:
5189 case dt_bomb:
5190
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5191 {
5192 case up:
5193 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5194 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5195 7259 scr->sflag[pos] = 0;
5196 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5197 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5198 7259 scr->sflag[pos+1] = 0;
5199 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5200 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5201 7259 scr->sflag[pos+16] = 0;
5202 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5203 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5204 7259 scr->sflag[pos+16+1] = 0;
5205
5206
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5207 {
5208 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5209 1824 DoorComboSets[d].doorcombo_u[type][0],
5210 1824 DoorComboSets[d].doorcset_u[type][0]);
5211 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5212 1824 DoorComboSets[d].doorcombo_u[type][1],
5213 1824 DoorComboSets[d].doorcset_u[type][1]);
5214 1824 }
5215
5216 7259 break;
5217
5218 case down:
5219 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5220 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5221 6784 scr->sflag[pos] = 0;
5222 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5223 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5224 6784 scr->sflag[pos+1] = 0;
5225 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5226 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5227 6784 scr->sflag[pos+16] = 0;
5228 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5229 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5230 6784 scr->sflag[pos+16+1] = 0;
5231
5232
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5233 {
5234 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5235 1321 DoorComboSets[d].doorcombo_d[type][2],
5236 1321 DoorComboSets[d].doorcset_d[type][2]);
5237 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5238 1321 DoorComboSets[d].doorcombo_d[type][3],
5239 1321 DoorComboSets[d].doorcset_d[type][3]);
5240 1321 }
5241
5242 6784 break;
5243
5244 case left:
5245 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5246 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5247 6362 scr->sflag[pos] = 0;
5248 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5249 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5250 6362 scr->sflag[pos+1] = 0;
5251 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5252 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5253 6362 scr->sflag[pos+16] = 0;
5254 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5255 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5256 6362 scr->sflag[pos+16+1] = 0;
5257 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5258 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5259 6362 scr->sflag[pos+32] = 0;
5260 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5261 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5262 6362 scr->sflag[pos+32+1] = 0;
5263
5264
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5265 {
5266 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5267 1489 DoorComboSets[d].doorcombo_l[type][0],
5268 1489 DoorComboSets[d].doorcset_l[type][0]);
5269 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5270 1489 DoorComboSets[d].doorcombo_l[type][2],
5271 1489 DoorComboSets[d].doorcset_l[type][2]);
5272 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5273 1489 DoorComboSets[d].doorcombo_l[type][4],
5274 1489 DoorComboSets[d].doorcset_l[type][4]);
5275 1489 }
5276
5277 6362 break;
5278
5279 case right:
5280 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5281 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5282 6712 scr->sflag[pos] = 0;
5283 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5284 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5285 6712 scr->sflag[pos+1] = 0;
5286 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5287 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5288 6712 scr->sflag[pos+16] = 0;
5289 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5290 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5291 6712 scr->sflag[pos+16+1] = 0;
5292 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5293 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5294 6712 scr->sflag[pos+32] = 0;
5295 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5296 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5297 6712 scr->sflag[pos+32+1] = 0;
5298
5299
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5300 {
5301 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5302 1654 DoorComboSets[d].doorcombo_r[type][0],
5303 1654 DoorComboSets[d].doorcset_r[type][0]);
5304 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5305 1654 DoorComboSets[d].doorcombo_r[type][2],
5306 1654 DoorComboSets[d].doorcset_r[type][2]);
5307 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5308 1654 DoorComboSets[d].doorcombo_r[type][4],
5309 1654 DoorComboSets[d].doorcset_r[type][4]);
5310 1654 }
5311
5312 6712 break;
5313 }
5314
5315 27117 break;
5316
5317 default:
5318 break;
5319 }
5320 28153 }
5321
5322 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5323 {
5324 706556 int32_t door_combo_set = scr->door_combo_set;
5325 706556 int32_t x = (pos&15)<<4;
5326 706556 int32_t y = (pos&0xF0);
5327 706556 int32_t d = door_combo_set;
5328 706556 x += offx;
5329 706556 y += offy;
5330
5331
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5332 {
5333 case up:
5334 322272 overcombo2(dest,x,y,
5335 161136 DoorComboSets[d].bombdoorcombo_u[0],
5336 161136 DoorComboSets[d].bombdoorcset_u[0]);
5337 322272 overcombo2(dest,x+16,y,
5338 161136 DoorComboSets[d].bombdoorcombo_u[1],
5339 161136 DoorComboSets[d].bombdoorcset_u[1]);
5340 161136 break;
5341
5342 case down:
5343 359286 overcombo2(dest,x,y,
5344 179643 DoorComboSets[d].bombdoorcombo_d[0],
5345 179643 DoorComboSets[d].bombdoorcset_d[0]);
5346 359286 overcombo2(dest,x+16,y,
5347 179643 DoorComboSets[d].bombdoorcombo_d[1],
5348 179643 DoorComboSets[d].bombdoorcset_d[1]);
5349 179643 break;
5350
5351 case left:
5352 392706 overcombo2(dest,x,y,
5353 196353 DoorComboSets[d].bombdoorcombo_l[0],
5354 196353 DoorComboSets[d].bombdoorcset_l[0]);
5355 392706 overcombo2(dest,x,y+16,
5356 196353 DoorComboSets[d].bombdoorcombo_l[1],
5357 196353 DoorComboSets[d].bombdoorcset_l[1]);
5358 392706 overcombo2(dest,x,y+16,
5359 196353 DoorComboSets[d].bombdoorcombo_l[2],
5360 196353 DoorComboSets[d].bombdoorcset_l[2]);
5361 196353 break;
5362
5363 case right:
5364 338848 overcombo2(dest,x,y,
5365 169424 DoorComboSets[d].bombdoorcombo_r[0],
5366 169424 DoorComboSets[d].bombdoorcset_r[0]);
5367 338848 overcombo2(dest,x,y+16,
5368 169424 DoorComboSets[d].bombdoorcombo_r[1],
5369 169424 DoorComboSets[d].bombdoorcset_r[1]);
5370 338848 overcombo2(dest,x,y+16,
5371 169424 DoorComboSets[d].bombdoorcombo_r[2],
5372 169424 DoorComboSets[d].bombdoorcset_r[2]);
5373 169424 break;
5374 }
5375 706556 }
5376
5377 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5378 {
5379
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5380 25173 return;
5381
5382 int32_t doortype;
5383
5384
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5385 {
5386 case dWALL:
5387 doortype=dt_wall;
5388 break;
5389
5390 case dWALK:
5391 doortype=dt_walk;
5392 break;
5393
5394 case dOPEN:
5395 12492 doortype=dt_pass;
5396 12492 break;
5397
5398 case dLOCKED:
5399 910 doortype=dt_lock;
5400 910 break;
5401
5402 case dUNLOCKED:
5403 1553 doortype=dt_olck;
5404 1553 break;
5405
5406 case dSHUTTER:
5407
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5408 {
5409 doortype=dt_osht;
5410 get_screen_state(scr->screen).open_doors = -4;
5411 break;
5412 }
5413
5414 [[fallthrough]];
5415 case d1WAYSHUTTER:
5416 3714 doortype=dt_shut;
5417 3714 break;
5418
5419 case dOPENSHUTTER:
5420 1694 doortype=dt_osht;
5421 1694 break;
5422
5423 case dBOSS:
5424 172 doortype=dt_boss;
5425 172 break;
5426
5427 case dOPENBOSS:
5428 67 doortype=dt_obos;
5429 67 break;
5430
5431 case dBOMBED:
5432 1138 doortype=dt_bomb;
5433 1138 break;
5434
5435 default:
5436 655 return;
5437 }
5438
5439
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5440 {
5441 case up:
5442 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5443 5629 break;
5444
5445 case down:
5446 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5447 5770 break;
5448
5449 case left:
5450 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5451 5111 break;
5452
5453 case right:
5454 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5455 5230 break;
5456 }
5457 47568 }
5458
5459 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5460 {
5461 /*
5462 #define dWALL 0 // 000 0
5463 #define dBOMB 6 // 011 0
5464 #define 8 // 100 0
5465 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5466 */
5467
5468
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5469 91 return;
5470
5471 int32_t doortype;
5472
5473
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5474 {
5475 case dWALL:
5476 doortype=dt_wall;
5477 break;
5478
5479 case dWALK:
5480 doortype=dt_walk;
5481 break;
5482
5483 case dOPEN:
5484 50 doortype=dt_pass;
5485 50 break;
5486
5487 case dLOCKED:
5488 doortype=dt_lock;
5489 break;
5490
5491 case dUNLOCKED:
5492 362 doortype=dt_olck;
5493 362 break;
5494
5495 case dSHUTTER:
5496
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5497 {
5498 doortype=dt_osht;
5499 get_screen_state(cur_screen).open_doors = -4;
5500 break;
5501 }
5502
5503 [[fallthrough]];
5504 case d1WAYSHUTTER:
5505 1757 doortype=dt_shut;
5506 1757 break;
5507
5508 case dOPENSHUTTER:
5509 3958 doortype=dt_osht;
5510 3958 break;
5511
5512 case dBOSS:
5513 4 doortype=dt_boss;
5514 4 break;
5515
5516 case dOPENBOSS:
5517 51 doortype=dt_obos;
5518 51 break;
5519
5520 case dBOMBED:
5521 231 doortype=dt_bomb;
5522 231 break;
5523
5524 default:
5525 return;
5526 }
5527
5528
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5529 {
5530 case up:
5531
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5532 {
5533 case dBOMBED:
5534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5535 {
5536 69 over_door(scr,dest,39,side,0,0);
5537 69 }
5538 [[fallthrough]];
5539 default:
5540 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5541 1860 break;
5542 }
5543
5544 1860 break;
5545
5546 case down:
5547
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5548 {
5549 case dBOMBED:
5550
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5551 {
5552 39 over_door(scr,dest,135,side,0,0);
5553 39 }
5554 [[fallthrough]];
5555 default:
5556 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5557 1357 break;
5558 }
5559
5560 1357 break;
5561
5562 case left:
5563
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5564 {
5565 case dBOMBED:
5566
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5567 {
5568 51 over_door(scr,dest,66,side,0,0);
5569 51 }
5570 [[fallthrough]];
5571 default:
5572 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5573 1514 break;
5574 }
5575
5576 1514 break;
5577
5578 case right:
5579
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5580 {
5581 case dBOMBED:
5582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5583 {
5584 72 over_door(scr,dest,77,side,0,0);
5585 72 }
5586 [[fallthrough]];
5587 default:
5588 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5589 1682 break;
5590 }
5591
5592 1682 break;
5593 }
5594 6504 }
5595
5596 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5597 {
5598
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5599 {
5600 586 putcombo(dest,x, y, combo, cset);
5601 586 }
5602 586 }
5603
5604 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5605 {
5606
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5607 {
5608 219 overcombo(dest,x, y, combo, cset);
5609 219 }
5610 293 }
5611
5612 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5613 {
5614 125 int32_t d = scr->door_combo_set;
5615
5616
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5617 {
5618 case up:
5619 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5620 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5621 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5622 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5623 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5624 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5625 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5626 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5627 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5628 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5629 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5630 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5631 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5632 43 DoorComboSets[d].bombdoorcombo_u[0],
5633 43 DoorComboSets[d].bombdoorcset_u[0]);
5634 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5635 43 DoorComboSets[d].bombdoorcombo_u[1],
5636 43 DoorComboSets[d].bombdoorcset_u[1]);
5637 43 break;
5638
5639 case down:
5640 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5641 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5642 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5643 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5644 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5645 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5646 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5647 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5648 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5649 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5650 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5651 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5652 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5653 39 DoorComboSets[d].bombdoorcombo_d[0],
5654 39 DoorComboSets[d].bombdoorcset_d[0]);
5655 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5656 39 DoorComboSets[d].bombdoorcombo_d[1],
5657 39 DoorComboSets[d].bombdoorcset_d[1]);
5658 39 break;
5659
5660 case left:
5661 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5662 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5663 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5664 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5665 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5666 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5667 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5668 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5669 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5670 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5671 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5672 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5673 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5674 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5675 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5676 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5677 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5678 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5679 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5680 6 DoorComboSets[d].bombdoorcombo_l[0],
5681 6 DoorComboSets[d].bombdoorcset_l[0]);
5682 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5683 6 DoorComboSets[d].bombdoorcombo_l[1],
5684 6 DoorComboSets[d].bombdoorcset_l[1]);
5685 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5686 6 DoorComboSets[d].bombdoorcombo_l[2],
5687 6 DoorComboSets[d].bombdoorcset_l[2]);
5688 6 break;
5689
5690 case right:
5691 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5692 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5693 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5694 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5695 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5696 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5697 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5698 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5699 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5700 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5701 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5702 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5703 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5704 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5705 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5706 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5707 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5708 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5709 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5710 37 DoorComboSets[d].bombdoorcombo_r[0],
5711 37 DoorComboSets[d].bombdoorcset_r[0]);
5712 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5713 37 DoorComboSets[d].bombdoorcombo_r[1],
5714 37 DoorComboSets[d].bombdoorcset_r[1]);
5715 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5716 37 DoorComboSets[d].bombdoorcombo_r[2],
5717 37 DoorComboSets[d].bombdoorcset_r[2]);
5718 37 break;
5719 }
5720 125 }
5721
5722 5361255 void openshutters(mapscr* scr)
5723 {
5724 5361255 bool opened_door = false;
5725
2/2
✓ Branch 0 taken 5361255 times.
✓ Branch 1 taken 21445020 times.
26806275 for(int32_t i=0; i<4; i++)
5726
2/2
✓ Branch 0 taken 21441062 times.
✓ Branch 1 taken 3958 times.
21448978 if(scr->door[i]==dSHUTTER)
5727 {
5728 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5729 3958 scr->door[i]=dOPENSHUTTER;
5730 3958 opened_door = true;
5731 3958 }
5732
5733 5361255 auto& combo_cache = combo_caches::shutter;
5734 2022925511 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5735
3/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2015953611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1610624 times.
2017564256 if (!combo_cache.minis[handle.data()].shutter)
5736 2017564235 return;
5737 21 auto cid = handle.data();
5738 21 auto& cmb = handle.combo();
5739
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
39 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
5740 {
5741 39 auto& trig = cmb.triggers[idx];
5742
2/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
39 if(trig.triggerflags[0] & combotriggerSHUTTER)
5743 {
5744 21 do_trigger_combo(handle, idx);
5745
1/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
21 if(handle.data() != cid) break;
5746 }
5747 18 }
5748 2017564256 });
5749
5750
2/2
✓ Branch 0 taken 5358524 times.
✓ Branch 1 taken 2731 times.
5361255 if(opened_door)
5751 2731 sfx(WAV_DOOR,128);
5752 5361255 }
5753
5754 15122012 void clear_darkroom_bitmaps()
5755 {
5756 15122012 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5757 15122012 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5758 15122012 }
5759
5760 16035826 bool is_dark(const mapscr* scr)
5761 {
5762 16035826 bool dark = scr->flags&fDARK;
5763
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16032104 times.
16035826 if (region_is_lit) return !dark;
5764 16032104 return dark;
5765 16035826 }
5766
5767 39230 bool scrolling_is_dark(const mapscr* scr)
5768 {
5769 39230 bool dark = scr->flags&fDARK;
5770
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39228 times.
39230 if (scrolling_region_is_lit) return !dark;
5771 39228 return dark;
5772 39230 }
5773
5774 36764 bool is_any_dark()
5775 {
5776 36764 bool dark = false;
5777 74784 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
5778 38020 dark |= (bool)(is_dark(scr));
5779 38020 });
5780 36764 return dark;
5781 }
5782
5783 410 static mapscr prev_origin_scrs[7];
5784 410 static std::set<int> loadscr_ffc_script_ids_to_remove;
5785
5786 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
5787 {
5788 mapscr* base_scr = screens[0];
5789 mapscr* previous_scr = &prev_origin_scrs[0];
5790
5791 for (int i = 0; i < 176; i++)
5792 {
5793 if (base_scr->data[i] == 0)
5794 {
5795 base_scr->data[i] = previous_scr->data[i];
5796 base_scr->sflag[i] = previous_scr->sflag[i];
5797 base_scr->cset[i] = previous_scr->cset[i];
5798 }
5799 }
5800
5801 for (int i = 0; i < 6; i++)
5802 {
5803 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
5804 {
5805 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
5806 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
5807
5808 for (int j = 0; j < 176; j++)
5809 {
5810 if (TheMaps[lm].data[j] == 0)
5811 {
5812 TheMaps[lm].data[j] = TheMaps[fm].data[j];
5813 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
5814 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
5815 }
5816 }
5817 }
5818 }
5819
5820 for (int i = 1; i <= 6; i++)
5821 {
5822 mapscr* scr = screens[i];
5823 previous_scr = &prev_origin_scrs[i];
5824
5825 if (scr->layermap[i] > 0)
5826 {
5827 for (int y = 0; y < 11; y++)
5828 {
5829 for (int x = 0; x < 16; x++)
5830 {
5831 int c = y*16+x;
5832
5833 if (scr->data[c]==0)
5834 {
5835 scr->data[c] = previous_scr->data[c];
5836 scr->sflag[c] = previous_scr->sflag[c];
5837 scr->cset[c] = previous_scr->cset[c];
5838 }
5839 }
5840 }
5841 }
5842 }
5843 }
5844
5845 37104 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
5846 {
5847 37104 std::vector<mapscr*> screens;
5848
5849
1/2
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
37104 const mapscr* source = get_canonical_scr(cur_map, screen);
5850
2/4
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37104 times.
✗ Branch 3 not taken.
37104 mapscr* base_scr = new mapscr(*source);
5851 37104 temporary_screens[screen*7] = base_scr;
5852
1/2
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
37104 screens.push_back(base_scr);
5853
5854 37104 base_scr->valid |= mVALID; // layer 0 is always valid
5855
5856
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35860 times.
37104 if (screen == cur_screen)
5857 35860 origin_scr = base_scr;
5858
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35860 times.
37104 if (screen == hero_screen)
5859 35860 hero_scr = prev_hero_scr = base_scr;
5860
5861
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36985 times.
37104 if (source->script > 0)
5862
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
5863
5864
2/2
✓ Branch 0 taken 37104 times.
✓ Branch 1 taken 222624 times.
259728 for (int i = 0; i < 6; i++)
5865 {
5866
2/2
✓ Branch 0 taken 173520 times.
✓ Branch 1 taken 49104 times.
222624 if(source->layermap[i]>0)
5867 {
5868
3/6
✓ Branch 0 taken 49104 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49104 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49104 times.
✗ Branch 5 not taken.
49104 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
5869 49104 layer_scr->map = cur_map;
5870 49104 layer_scr->screen = screen;
5871
1/2
✓ Branch 0 taken 49104 times.
✗ Branch 1 not taken.
49104 screens.push_back(layer_scr);
5872 49104 }
5873 else
5874 {
5875
1/2
✓ Branch 0 taken 173520 times.
✗ Branch 1 not taken.
173520 mapscr* layer_scr = new mapscr();
5876 173520 layer_scr->map = cur_map;
5877 173520 layer_scr->screen = screen;
5878
1/2
✓ Branch 0 taken 173520 times.
✗ Branch 1 not taken.
173520 screens.push_back(layer_scr);
5879 }
5880 222624 temporary_screens[screen*7+i+1] = screens[i+1];
5881 222624 }
5882
5883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37104 times.
37104 if (screen_overlay)
5884 handle_screen_overlay(screens);
5885
5886
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36960 times.
37104 if (ffc_overlay)
5887 {
5888 144 mapscr* previous_scr = &prev_origin_scrs[0];
5889
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
5890
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
5891 {
5892
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
5893 {
5894
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
5895 274 ffc.screen_spawned = screen;
5896
5897
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
5898
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
5899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
5900 {
5901 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
5902 }
5903 274 }
5904 4608 }
5905 144 }
5906
5907
1/2
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
1142145 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
5908
1/2
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
37104 int num_ffcs = base_scr->numFFC();
5909
2/2
✓ Branch 0 taken 1105041 times.
✓ Branch 1 taken 37104 times.
1142145 for (word i = 0; i < num_ffcs; i++)
5910 {
5911 1105041 base_scr->ffcs[i].screen_spawned = screen;
5912
1/2
✓ Branch 0 taken 1105041 times.
✗ Branch 1 not taken.
1105041 base_scr->ffcs[i].x += offx;
5913
1/2
✓ Branch 0 taken 1105041 times.
✗ Branch 1 not taken.
1105041 base_scr->ffcs[i].y += offy;
5914 1105041 }
5915 37104 }
5916
5917 37104 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
5918 {
5919 37104 mapscr* base_scr = get_scr(screen);
5920 37104 int mi = mapind(cur_map, screen);
5921
5922 // Apply perm secrets, if applicable.
5923
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 25584 times.
37104 if (canPermSecret(dmap, screen))
5924 {
5925
2/2
✓ Branch 0 taken 23058 times.
✓ Branch 1 taken 2526 times.
25584 if(game->maps[mi] & mSECRET) // if special stuff done before
5926 {
5927 2526 reveal_hidden_stairs(base_scr, screen, false);
5928 2526 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
5929 2526 }
5930
2/2
✓ Branch 0 taken 25581 times.
✓ Branch 1 taken 3 times.
25584 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
5931 {
5932
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
5933 {
5934 21 mapscr* layer_scr = get_scr_layer(screen, layer);
5935
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
5936 {
5937 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
5938
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
5939 {
5940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
5941 {
5942 3 layer_scr->data[pos] += 1;
5943 3 }
5944 3 }
5945 3696 }
5946 21 }
5947 3 }
5948 25584 }
5949
5950 37104 auto screen_handles = create_screen_handles(base_scr);
5951
5952 37104 int destlvl = DMaps[dmap].level;
5953 37104 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
5954 37104 toggle_gswitches_load(screen_handles);
5955
5956 37104 bool should_check_for_state_things = (screen < 0x80);
5957
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36197 times.
37104 if (should_check_for_state_things)
5958 {
5959
2/2
✓ Branch 0 taken 35825 times.
✓ Branch 1 taken 372 times.
36197 if (game->maps[mi]&mLOCKBLOCK)
5960 372 remove_lockblocks(screen_handles);
5961
2/2
✓ Branch 0 taken 36139 times.
✓ Branch 1 taken 58 times.
36197 if (game->maps[mi]&mBOSSLOCKBLOCK)
5962 58 remove_bosslockblocks(screen_handles);
5963
2/2
✓ Branch 0 taken 36041 times.
✓ Branch 1 taken 156 times.
36197 if (game->maps[mi]&mCHEST)
5964 156 remove_chests(screen_handles);
5965
1/2
✓ Branch 0 taken 36197 times.
✗ Branch 1 not taken.
36197 if (game->maps[mi]&mLOCKEDCHEST)
5966 remove_lockedchests(screen_handles);
5967
2/2
✓ Branch 0 taken 36186 times.
✓ Branch 1 taken 11 times.
36197 if (game->maps[mi]&mBOSSCHEST)
5968 11 remove_bosschests(screen_handles);
5969
5970 36197 clear_xdoors_mi(screen_handles, mi, true);
5971 36197 clear_xstatecombos_mi(screen_handles, mi, true);
5972 36197 }
5973
5974 // check doors
5975
2/2
✓ Branch 0 taken 25583 times.
✓ Branch 1 taken 11521 times.
37104 if (isdungeon(dmap, screen))
5976 {
5977
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
5978 {
5979 46084 int32_t door=base_scr->door[i];
5980
5981
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
5982 {
5983 case d1WAYSHUTTER:
5984 case dSHUTTER:
5985
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == hero_screen)
5986 {
5987 1694 base_scr->door[i]=dOPENSHUTTER;
5988 1694 }
5989
5990 5303 get_screen_state(screen).open_doors = -4;
5991 5303 break;
5992
5993 case dLOCKED:
5994
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5995 {
5996 1473 base_scr->door[i]=dUNLOCKED;
5997 1473 }
5998
5999 2372 break;
6000
6001 case dBOSS:
6002
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(1<<i))
6003 {
6004 62 base_scr->door[i]=dOPENBOSS;
6005 62 }
6006
6007 230 break;
6008
6009 case dBOMB:
6010
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(1<<i))
6011 {
6012 1087 base_scr->door[i]=dBOMBED;
6013 1087 }
6014
6015 1704 break;
6016 }
6017
6018 46084 update_door(base_scr, i, base_scr->door[i]);
6019
6020
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6021 {
6022 5303 base_scr->door[i]=door;
6023 5303 }
6024 46084 }
6025 11521 }
6026
6027
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36967 times.
37104 if (!(base_scr->flags3 & fCYCLEONINIT))
6028 36967 return;
6029
6030
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6031 {
6032
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
6033 {
6034 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6035
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6036 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6037
6038
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
6039 {
6040 90464 int32_t c=layerscreen->data[i];
6041
6042 // New screen flag: Cycle Combos At Screen Init
6043
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6044 {
6045 65 int32_t r = 0;
6046
6047
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6048 {
6049 84 newcombo const& cmb = combobuf[c];
6050 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6052 84 layerscreen->data[i] = cid;
6053
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6055 84 c = layerscreen->data[i];
6056 }
6057 65 }
6058 90464 }
6059 514 }
6060 959 }
6061 37104 }
6062
6063 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6064 //
6065 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6066 // the game, etc...)
6067 //
6068 // Note: for regions, only the initial screen load calls this function. Simply walking between
6069 // screens in the same region does not use this, because every screen in a region is loaded into
6070 // temporary memory up front.
6071 //
6072 // If scr >= 0x80, `hero_screen` will be saved to `home_screen` and also be loaded into
6073 // `special_warp_return_scr`.
6074 //
6075 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6076 // on all layers (but only where the new screen has a 0 combo).
6077 //
6078 // TODO: loadscr should set curdmap, but currently callers do that.
6079 35860 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6080 {
6081 35860 zapp_reporting_set_tag("screen", screen);
6082
2/2
✓ Branch 0 taken 8930 times.
✓ Branch 1 taken 26930 times.
35860 if (destdmap != -1)
6083 8930 zapp_reporting_set_tag("dmap", destdmap);
6084
6085 35860 int32_t orig_destdmap = destdmap;
6086
2/2
✓ Branch 0 taken 8930 times.
✓ Branch 1 taken 26930 times.
35860 if (destdmap < 0) destdmap = cur_dmap;
6087
6088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35860 times.
35860 if (replay_is_active())
6089 {
6090
1/2
✓ Branch 0 taken 35860 times.
✗ Branch 1 not taken.
35860 if (replay_get_mode() == ReplayMode::ManualTakeover)
6091 replay_stop_manual_takeover();
6092
6093
2/2
✓ Branch 0 taken 26930 times.
✓ Branch 1 taken 8930 times.
35860 if (orig_destdmap != -1)
6094 {
6095
2/2
✓ Branch 0 taken 7856 times.
✓ Branch 1 taken 1074 times.
8930 if (strlen(DMaps[orig_destdmap].name) > 0)
6096 {
6097
1/2
✓ Branch 0 taken 7856 times.
✗ Branch 1 not taken.
7856 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6098 7856 }
6099 else
6100 {
6101
1/2
✓ Branch 0 taken 1074 times.
✗ Branch 1 not taken.
1074 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6102 }
6103 8930 }
6104 35860 replay_step_comment_loadscr(screen);
6105
6106 // Reset the rngs and frame count so that recording steps can be modified without impacting
6107 // behavior of later screens.
6108 35860 replay_sync_rng();
6109 35860 }
6110
6111
2/2
✓ Branch 0 taken 1707573 times.
✓ Branch 1 taken 35860 times.
1743433 for (auto& state : get_screen_states())
6112 1707573 state.second.triggered_secrets = false;
6113 35860 slopes.clear();
6114 35860 Hero.clear_platform_ffc();
6115 35860 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6116 35860 clear_darkroom_bitmaps();
6117 35860 msgscr = nullptr;
6118
6119
2/2
✓ Branch 0 taken 50399485 times.
✓ Branch 1 taken 35860 times.
50435345 for (word x=0; x<animated_combos; x++)
6120 {
6121
2/2
✓ Branch 0 taken 20920072 times.
✓ Branch 1 taken 29479413 times.
50399485 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6122 {
6123 20920072 combobuf[animated_combo_table4[x][0]].aclk = 0;
6124 20920072 }
6125 50399485 }
6126 35860 reset_combo_animations2();
6127 35860 region_is_lit = false;
6128
6129 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6130 // of the new ones.
6131 35860 bool origin_ffc_overlay = false;
6132
2/2
✓ Branch 0 taken 34723 times.
✓ Branch 1 taken 1137 times.
35860 if (origin_scr)
6133 {
6134
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34721 times.
34723 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6135 {
6136 34721 int c = origin_scr->numFFC();
6137
2/2
✓ Branch 0 taken 34577 times.
✓ Branch 1 taken 1038879 times.
1073456 for (int i = 0; i < c; i++)
6138 {
6139
2/2
✓ Branch 0 taken 1038735 times.
✓ Branch 1 taken 144 times.
1038879 if (origin_scr->ffcs[i].flags&ffc_carryover)
6140 {
6141 144 origin_ffc_overlay = true;
6142 144 break;
6143 }
6144 1038735 }
6145 34721 }
6146
6147
3/4
✓ Branch 0 taken 34723 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34579 times.
34723 if (origin_screen_overlay || origin_ffc_overlay)
6148 {
6149
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6150 {
6151 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6152
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6153 1008 prev_origin_scrs[i] = *prev_scr;
6154 else
6155 prev_origin_scrs[i] = {};
6156 1008 }
6157 144 }
6158 34723 }
6159
6160 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6161 // them, but scripts that need their data to persist will be removed.
6162 35860 loadscr_ffc_script_ids_to_remove.clear();
6163
2/2
✓ Branch 0 taken 74707640 times.
✓ Branch 1 taken 35860 times.
74743500 for (auto& key : scriptEngineDatas | std::views::keys)
6164 {
6165
2/2
✓ Branch 0 taken 73585735 times.
✓ Branch 1 taken 1121905 times.
74707640 if (key.first == ScriptType::FFC)
6166 1121905 loadscr_ffc_script_ids_to_remove.insert(key.second);
6167 }
6168
6169 35860 load_region(destdmap, screen);
6170
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 34953 times.
35860 home_screen = screen >= 0x80 ? hero_screen : cur_screen;
6171 35860 hero_screen = screen;
6172
6173 35860 cpos_clear_all();
6174 35860 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6175 35860 FFCore.clear_combo_scripts();
6176
6177
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35696 times.
35860 if (is_in_scrolling_region())
6178 {
6179
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6180 {
6181
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6182 {
6183
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6184
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6185 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6186 1408 }
6187 20992 }
6188 164 }
6189 else
6190 {
6191 35696 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6192 }
6193
6194 35860 prepare_current_region_handles();
6195
6196
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35696 times.
35860 if (is_in_scrolling_region())
6197 {
6198
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6199 {
6200
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6201 {
6202 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6203 1408 }
6204 20992 }
6205 164 }
6206 else
6207 {
6208 35696 load_a_screen_and_layers_post(destdmap, screen, ldir);
6209 }
6210
6211 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6212
2/2
✓ Branch 0 taken 34953 times.
✓ Branch 1 taken 907 times.
35860 if (screen >= 0x80)
6213
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6214
6215 35860 update_slope_comboposes();
6216 35860 cpos_force_update();
6217 35860 trig_trigger_groups();
6218
6219
2/2
✓ Branch 0 taken 1121631 times.
✓ Branch 1 taken 35860 times.
1157491 for (int index : loadscr_ffc_script_ids_to_remove)
6220 {
6221 1121631 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6222 }
6223
6224 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6225 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6226 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6227 // It is up to the quest designer to make their subscreen be actually transparent.
6228 //
6229 // When not in "extended height mode" (otherwise 56 is 0):
6230 // - playing_field_offset: 56, but changes during earthquakes
6231 // - original_playing_field_offset: always 56
6232 //
6233 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6234 // - yofs of sprites
6235 // - bitmap y offsets in draw_screen
6236 // - drawing offsets for putscr, do_layer
6237 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6238 // - lots more
6239 //
6240 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6241
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35718 times.
35860 if (is_extended_height_mode())
6242 {
6243 142 playing_field_offset = 0;
6244 142 original_playing_field_offset = 0;
6245 // A few sprites exist as globals, so we must manually reset them.
6246 142 Hero.yofs = 0;
6247 142 mblock2.yofs = 0;
6248 142 }
6249 else
6250 {
6251 35718 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6252 35718 original_playing_field_offset = 56;
6253 }
6254 35860 is_any_room_dark = is_any_dark();
6255
6256 35860 game->load_portal();
6257 35860 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6258
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35825 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35860 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6259 {
6260 delete Hero.lift_wpn;
6261 Hero.lift_wpn = nullptr;
6262 }
6263
6264 35860 enemy_spawning_has_checked_been_here = false;
6265 35860 markBmap(-1, hero_screen);
6266 35860 Hero.maybe_begin_advanced_maze();
6267 35860 }
6268
6269 // Don't use this directly! Use `loadscr` instead.
6270 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6271 {
6272
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6273
6274 907 mapscr previous_scr = *special_warp_return_scr;
6275 907 mapscr* scr = special_warp_return_scr;
6276
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6277
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6278
6279
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6280 {
6281
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 5059 times.
5442 if (scr->layermap[i-1] > 0)
6282
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6283 else
6284 5059 special_warp_return_scrs[i] = {};
6285 5442 }
6286
6287 907 scr->valid |= mVALID; //layer 0 is always valid
6288
6289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6290 {
6291 scr->script = source->script;
6292 for ( int32_t q = 0; q < 8; q++ )
6293 {
6294 scr->screeninitd[q] = source->screeninitd[q];
6295 }
6296 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6297 }
6298 else
6299 {
6300 907 scr->script = 0;
6301 }
6302
6303
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6304 {
6305 for(int32_t c=0; c< 176; ++c)
6306 {
6307 if(scr->data[c]==0)
6308 {
6309 scr->data[c]=previous_scr.data[c];
6310 scr->sflag[c]=previous_scr.sflag[c];
6311 scr->cset[c]=previous_scr.cset[c];
6312 }
6313 }
6314
6315 for(int32_t i=0; i<6; i++)
6316 {
6317 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6318 {
6319 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6320 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6321
6322 for(int32_t c=0; c< 176; ++c)
6323 {
6324 if(TheMaps[lm].data[c]==0)
6325 {
6326 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6327 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6328 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6329 }
6330 }
6331 }
6332 }
6333 }
6334
6335
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6336
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6337
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6338 {
6339 28993 scr->ffcs[i].screen_spawned = screen;
6340
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6341
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6342 28993 }
6343
6344 907 int mi = mapind(cur_map, screen);
6345
6346 // Apply perm secrets, if applicable.
6347
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6348 {
6349
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6350 {
6351
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6352
6353
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6354
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6355 204 bool do_replay_comment = true;
6356 204 bool from_active_screen = false;
6357
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6358 204 }
6359
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6360 {
6361 for (int layer = 0; layer <= 6; layer++)
6362 {
6363 mapscr* tscr = &special_warp_return_scrs[layer];
6364 for (int pos = 0; pos < 176; pos++)
6365 {
6366 newcombo const* cmb = &combobuf[tscr->data[pos]];
6367 if(cmb->type == cLIGHTTARGET)
6368 {
6369 if(!(cmb->usrflags&cflag1)) //Unlit version
6370 {
6371 tscr->data[pos] += 1;
6372 }
6373 }
6374 }
6375 }
6376 }
6377 536 }
6378
6379 screen_handles_t screen_handles;
6380
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6381
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1289 times.
✓ Branch 3 taken 5060 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6382
6383
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6384
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6385
6386
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6387 {
6388
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6389 5 }
6390
6391
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6392 {
6393
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6394 1 }
6395
6396
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6397 {
6398 remove_chests(screen_handles);
6399 }
6400
6401
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6402 {
6403 remove_lockedchests(screen_handles);
6404 }
6405
6406
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6407 {
6408 remove_bosschests(screen_handles);
6409 }
6410
6411
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6412
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6413
6414 // check doors
6415
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 371 times.
✓ Branch 3 taken 536 times.
907 if (isdungeon(destdmap, screen))
6416 {
6417
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6418 {
6419 1484 int32_t door=scr->door[i];
6420
6421
4/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 1295 times.
1484 switch(door)
6422 {
6423 case d1WAYSHUTTER:
6424 case dSHUTTER:
6425
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1295 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1295 if ((ldir^1)==i && screen == home_screen)
6426 {
6427 scr->door[i]=dOPENSHUTTER;
6428 }
6429
6430
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1190 times.
1295 get_screen_state(screen).open_doors = -4;
6431 105 break;
6432
6433 case dLOCKED:
6434
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 11 times.
91 if(game->maps[mi]&(1<<i))
6435 {
6436 80 scr->door[i]=dUNLOCKED;
6437 80 }
6438
6439 91 break;
6440
6441 case dBOSS:
6442
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
9 if(game->maps[mi]&(1<<i))
6443 {
6444 5 scr->door[i]=dOPENBOSS;
6445 5 }
6446
6447 9 break;
6448
6449 case dBOMB:
6450
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 38 times.
89 if(game->maps[mi]&(1<<i))
6451 {
6452 51 scr->door[i]=dBOMBED;
6453 51 }
6454
6455 89 break;
6456 }
6457
6458
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 1190 times.
294 update_door(scr, i, scr->door[i]);
6459
6460
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6461 {
6462 105 scr->door[i]=door;
6463 105 }
6464 1484 }
6465 371 }
6466
6467
2/2
✓ Branch 0 taken 6915 times.
✓ Branch 1 taken 731 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6468 {
6469
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 1473 times.
✓ Branch 2 taken 2763 times.
✓ Branch 3 taken 2679 times.
6915 if (j<0 || scr->layermap[j] > 0)
6470 {
6471
4/4
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 383 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
4236 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6472 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6473
6474
2/2
✓ Branch 0 taken 224660 times.
✓ Branch 1 taken 3670 times.
228330 for(int32_t i=0; i<176; ++i)
6475 {
6476 224660 int32_t c=layerscreen->data[i];
6477
6478 // New screen flag: Cycle Combos At Screen Init
6479
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 224654 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2380 times.
✓ Branch 7 taken 2380 times.
224660 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6480 {
6481 2380 int32_t r = 0;
6482
6483
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2380 while(combobuf[c].can_cycle() && r++ < 10)
6484 {
6485 newcombo const& cmb = combobuf[c];
6486 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6487 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6488 layerscreen->data[i] = cid;
6489 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6490 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6491 c = layerscreen->data[i];
6492 }
6493 }
6494 227040 }
6495 3670 }
6496 6349 }
6497 5491 }
6498
6499 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6500 // instead returns an array of mapscr.
6501 // Used to draw/save the map.
6502 45680 std::array<mapscr, 7> loadscr2(int32_t screen)
6503 {
6504 45680 std::array<mapscr, 7> scrs;
6505 45680 mapscr* scr = &scrs[0];
6506
6507
2/2
✓ Branch 0 taken 64716181 times.
✓ Branch 1 taken 45680 times.
64761861 for(word x=0; x<animated_combos; x++)
6508 {
6509
2/2
✓ Branch 0 taken 31963685 times.
✓ Branch 1 taken 32752496 times.
64716181 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6510 {
6511 32752496 combobuf[animated_combo_table4[x][0]].aclk=0;
6512 32752496 }
6513 64716181 }
6514
6515
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 const mapscr* source = get_canonical_scr(cur_map, screen);
6516
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!source->is_valid())
6517 {
6518 scrs[0].valid = 0;
6519 return scrs;
6520 }
6521
6522
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 *scr = *get_canonical_scr(cur_map, screen);
6523
2/2
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
319760 for (int i = 1; i <= 6; i++)
6524 {
6525
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 209266 times.
274080 if (scr->layermap[i-1] > 0)
6526
2/4
✓ Branch 0 taken 64814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64814 times.
✗ Branch 3 not taken.
64814 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6527 else
6528 209266 scrs[i] = {};
6529 274080 }
6530
6531 screen_handles_t screen_handles;
6532
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i < 7; i++)
6533
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6534
6535 45680 int mi = mapind(cur_map, screen);
6536
6537
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if(canPermSecret(-1,screen))
6538 {
6539
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5730 times.
✓ Branch 3 taken 39896 times.
45626 if(game->maps[mi]&mSECRET) // if special stuff done before
6540 {
6541
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 reveal_hidden_stairs(scr, screen, false);
6542 5730 bool from_active_screen = false;
6543 5730 bool do_replay_comment = true;
6544
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6545 5730 }
6546
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45609 times.
✓ Branch 3 taken 17 times.
45626 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6547 {
6548
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6549 {
6550 119 mapscr* tscr = &scrs[layer];
6551
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6552 {
6553 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6554
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6555 {
6556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6557 {
6558 17 tscr->data[pos] += 1;
6559 17 }
6560 17 }
6561 20944 }
6562 119 }
6563 17 }
6564 45626 }
6565
6566
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
✓ Branch 3 taken 45447 times.
45680 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6567 {
6568
1/2
✓ Branch 0 taken 233 times.
✗ Branch 1 not taken.
233 remove_lockblocks(screen_handles);
6569 233 }
6570
6571
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45679 times.
45680 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6572 {
6573
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6574 1 }
6575
6576
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45579 times.
45680 if(game->maps[mi]&mCHEST) // if special stuff done before
6577 {
6578
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6579 101 }
6580
6581
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45656 times.
45680 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6582 {
6583
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6584 24 }
6585
6586
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6587 {
6588 remove_bosschests(screen_handles);
6589 }
6590
6591
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xdoors(screen_handles);
6592
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xstatecombos(screen_handles);
6593
6594 // check doors
6595
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 45626 times.
45680 if (isdungeon(screen))
6596 {
6597
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6598 {
6599 216 int32_t door=scr->door[i];
6600 216 bool putit=true;
6601
6602
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6603 {
6604 case d1WAYSHUTTER:
6605 case dSHUTTER:
6606 61 break;
6607
6608 case dLOCKED:
6609
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(1<<i))
6610 {
6611 12 scr->door[i]=dUNLOCKED;
6612 12 }
6613
6614 12 break;
6615
6616 case dBOSS:
6617
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(1<<i))
6618 {
6619 scr->door[i]=dOPENBOSS;
6620 }
6621
6622 4 break;
6623
6624 case dBOMB:
6625 if(game->maps[mi]&(1<<i))
6626 {
6627 scr->door[i]=dBOMBED;
6628 }
6629
6630 break;
6631 }
6632
6633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6634 {
6635
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6636 216 }
6637
6638
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6639 {
6640 61 scr->door[i]=door;
6641 61 }
6642 216 }
6643 54 }
6644
6645
2/2
✓ Branch 0 taken 319760 times.
✓ Branch 1 taken 45680 times.
365440 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6646 {
6647
4/4
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
✓ Branch 2 taken 64814 times.
✓ Branch 3 taken 209266 times.
319760 if (j < 0 || scr->layermap[j] > 0)
6648 {
6649
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 45680 times.
110494 mapscr *layerscreen= (j<0 ? scr
6650 64814 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6651
6652
2/2
✓ Branch 0 taken 19446944 times.
✓ Branch 1 taken 110494 times.
19557438 for(int32_t i=0; i<176; ++i)
6653 {
6654 19446944 int32_t c=layerscreen->data[i];
6655
6656 // New screen flag: Cycle Combos At Screen Init
6657
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19446944 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19446944 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6658 {
6659 int32_t r = 0;
6660
6661 while(combobuf[c].can_cycle() && r++ < 10)
6662 {
6663 newcombo const& cmb = combobuf[c];
6664 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6665 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6666 layerscreen->data[i] = cid;
6667 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6668 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6669 c = layerscreen->data[i];
6670 }
6671 }
6672 19446944 }
6673 110494 }
6674 319760 }
6675
6676 45680 return scrs;
6677
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 }
6678
6679 19021382 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6680 {
6681 // This is a bogus value while screenscrolling == true, but that's ok
6682 // because it is only used to calculate the rpos, and during screenscrolling
6683 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6684 // is always the same no matter the value of scr.
6685 19021382 int screen = get_screen_for_world_xy(x, y);
6686
6687 19021382 x -= viewport.x;
6688 19021382 y -= viewport.y;
6689
6690
3/6
✓ Branch 0 taken 19021382 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19021382 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19021382 times.
19021382 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6691 {
6692 rectfill(dest,x,y,x+255,y+175,0);
6693 return;
6694 }
6695
6696 37913854 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6697
2/2
✓ Branch 0 taken 128910 times.
✓ Branch 1 taken 18892472 times.
19021382 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG);
6698
6699 int start_x, end_x, start_y, end_y;
6700 19021382 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6701
2/2
✓ Branch 0 taken 19021382 times.
✓ Branch 1 taken 202608822 times.
221630204 for (int cy = start_y; cy < end_y; cy++)
6702 {
6703
2/2
✓ Branch 0 taken 3076713730 times.
✓ Branch 1 taken 202608822 times.
3279322552 for (int cx = start_x; cx < end_x; cx++)
6704 {
6705 3076713730 int i = cx + cy*16;
6706
2/2
✓ Branch 0 taken 357902710 times.
✓ Branch 1 taken 2718811020 times.
3076713730 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6707 3076713730 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6708 3076713730 }
6709 202608822 }
6710 19021382 }
6711
6712 15544470 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6713 {
6714
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15544470 times.
15544470 if (!show_layers[0])
6715 {
6716 return;
6717 }
6718
6719 15544470 x -= viewport.x;
6720 15544470 y -= viewport.y;
6721
6722
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15544470 times.
31225258 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6723 15680788 mapscr* scr = screen_handles[0].base_scr;
6724
1/2
✓ Branch 0 taken 15680788 times.
✗ Branch 1 not taken.
15680788 if (!scr->is_valid())
6725 return;
6726
6727
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 15557377 times.
15680788 if(scr->door[0]==dBOMBED)
6728 {
6729 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6730 123411 }
6731
6732
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 15537679 times.
15680788 if(scr->door[1]==dBOMBED)
6733 {
6734 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6735 143109 }
6736
6737
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 15524926 times.
15680788 if(scr->door[2]==dBOMBED)
6738 {
6739 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6740 155862 }
6741
6742
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 15548499 times.
15680788 if(scr->door[3]==dBOMBED)
6743 {
6744 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6745 132289 }
6746 15680788 });
6747 15544470 }
6748
6749 3340594 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6750 {
6751
2/4
✓ Branch 0 taken 3340594 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3340594 times.
✗ Branch 3 not taken.
3340594 if (!scr->is_valid() || !show_layers[0])
6752 return;
6753
6754 3340594 x -= viewport.x;
6755 3340594 y -= viewport.y;
6756
6757
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3302938 times.
3340594 if(scr->door[0]==dBOMBED)
6758 {
6759 37656 over_door(scr,dest,39,up,x,y);
6760 37656 }
6761
6762
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3304099 times.
3340594 if(scr->door[1]==dBOMBED)
6763 {
6764 36495 over_door(scr,dest,135,down,x,y);
6765 36495 }
6766
6767
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3300154 times.
3340594 if(scr->door[2]==dBOMBED)
6768 {
6769 40440 over_door(scr,dest,66,left,x,y);
6770 40440 }
6771
6772
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3303531 times.
3340594 if(scr->door[3]==dBOMBED)
6773 {
6774 37063 over_door(scr,dest,77,right,x,y);
6775 37063 }
6776 3340594 }
6777 232737041 static inline bool onSwitch(newcombo const& cmb, zfix const& switchblockstate)
6778 {
6779
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 232737041 times.
✓ Branch 2 taken 232716146 times.
✓ Branch 3 taken 20895 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20895 times.
232737041 return (switchblockstate < 0 || (cmb.attributes[2]>0 && (zslongToFix(cmb.attributes[2]) - zslongToFix(zc_max(cmb.attributes[3], 0))) <=switchblockstate));
6780 }
6781 56124176 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
6782 {
6783 56124176 return _walkflag(zx,zy,cnt,0_zf);
6784 }
6785
6786 133020390 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& switchblockstate, bool is_temp_screens)
6787 {
6788 133020390 int x = zx.getRound(), y = zy.getRound();
6789 133020390 int pos = COMBOPOS(x % 256, y % 176);
6790 133020390 const newcombo& c = combobuf[s0->data[pos]];
6791 133020390 const newcombo& c1 = combobuf[s1->data[pos]];
6792 133020390 const newcombo& c2 = combobuf[s2->data[pos]];
6793
4/4
✓ Branch 0 taken 131024949 times.
✓ Branch 1 taken 1995441 times.
✓ Branch 2 taken 131015489 times.
✓ Branch 3 taken 9460 times.
266243068 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6794
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 131116624 times.
✓ Branch 2 taken 2101809 times.
✓ Branch 3 taken 4245 times.
133020390 (iswater_type(c2.type))) && DRIEDLAKE);
6795 133222678 int32_t b=1;
6796
2/2
✓ Branch 0 taken 65677301 times.
✓ Branch 1 taken 67545377 times.
133222678 if(x&8) b<<=2;
6797
2/2
✓ Branch 0 taken 62238464 times.
✓ Branch 1 taken 70984214 times.
133222678 if(y&8) b<<=1;
6798
6799 133222678 int32_t cwalkflag = c.walk;
6800
3/8
✓ Branch 0 taken 133121534 times.
✓ Branch 1 taken 101144 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 133121534 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
133222678 if(is_temp_screens && onSwitch(c,switchblockstate) && c.type == cCSWITCHBLOCK && c.usrflags&cflag9) cwalkflag &= (c.walk>>4)^0xF;
6801
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 133172106 times.
✓ Branch 2 taken 2096585 times.
✓ Branch 3 taken 2046013 times.
✓ Branch 4 taken 2096585 times.
✓ Branch 5 taken 133121534 times.
✓ Branch 6 taken 2096585 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2096585 times.
✗ Branch 9 not taken.
133222678 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6802
2/2
✓ Branch 0 taken 63476708 times.
✓ Branch 1 taken 69644826 times.
133121534 if (s1 != s0)
6803 {
6804
5/8
✓ Branch 0 taken 69644826 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1980 times.
✓ Branch 3 taken 69642846 times.
✓ Branch 4 taken 1980 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1980 times.
69644826 if(is_temp_screens && onSwitch(c1,switchblockstate) && c1.type == cCSWITCHBLOCK && c1.usrflags&cflag9) cwalkflag &= (c1.walk>>4)^0xF;
6805
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69631117 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69642846 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
6806
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69579940 times.
69642846 else if (c1.type == cBRIDGE)
6807 {
6808
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6809 {
6810 62906 int efflag = (c1.walk & 0xF0)>>4;
6811 62906 int newsolid = (c1.walk & 0xF);
6812 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6813 62906 }
6814 else cwalkflag &= c1.walk;
6815 62906 }
6816
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69568211 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69579940 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
6817 69579940 else cwalkflag |= c1.walk;
6818 69644826 }
6819
2/2
✓ Branch 0 taken 103150853 times.
✓ Branch 1 taken 29970681 times.
133121534 if (s2 != s0)
6820 {
6821
2/8
✓ Branch 0 taken 29970681 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 29970681 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29970681 if(is_temp_screens && onSwitch(c2,switchblockstate) && c2.type == cCSWITCHBLOCK && c2.usrflags&cflag9) cwalkflag &= (c2.walk>>4)^0xF;
6822
4/10
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29968527 times.
✓ Branch 2 taken 2154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2154 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
29970681 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
6823
2/2
✓ Branch 0 taken 7790 times.
✓ Branch 1 taken 29962891 times.
29970681 else if (c2.type == cBRIDGE)
6824 {
6825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7790 times.
7790 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6826 {
6827 7790 int efflag = (c2.walk & 0xF0)>>4;
6828 7790 int newsolid = (c2.walk & 0xF);
6829 7790 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6830 7790 }
6831 else cwalkflag &= c2.walk;
6832 7790 }
6833
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29960737 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29962891 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
6834 29962891 else cwalkflag |= c2.walk;
6835 29970681 }
6836
6837
4/4
✓ Branch 0 taken 29570179 times.
✓ Branch 1 taken 103551355 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29569231 times.
133121534 if((cwalkflag&b) && !dried)
6838 29569231 return true;
6839
6840
3/4
✓ Branch 0 taken 103552303 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103535892 times.
✓ Branch 3 taken 16411 times.
103552303 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
6841
6842 103535892 return false;
6843 133121534 }
6844
6845 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
6846 133121534 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& switchblockstate)
6847 {
6848 133121534 int x = zx.getRound(), y = zy.getRound();
6849 133121534 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
6850 133121534 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6851 133121534 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6852
2/2
✓ Branch 0 taken 63476708 times.
✓ Branch 1 taken 69644826 times.
133121534 if (!s1->valid) s1 = s0;
6853
2/2
✓ Branch 0 taken 103150853 times.
✓ Branch 1 taken 29970681 times.
133121534 if (!s2->valid) s2 = s0;
6854 133121534 return _walkflag_new(s0, s1, s2, zx, zy, switchblockstate, true);
6855 }
6856
6857 128672262 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& switchblockstate)
6858 {
6859 128672262 int max_x = world_w;
6860 128672262 int max_y = world_h;
6861
2/2
✓ Branch 0 taken 68629525 times.
✓ Branch 1 taken 60042737 times.
128672262 if (!get_qr(qr_LTTPWALK))
6862 {
6863 60042737 max_x -= 7;
6864 60042737 max_y -= 7;
6865 60042737 }
6866
4/4
✓ Branch 0 taken 128401442 times.
✓ Branch 1 taken 270820 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 128318174 times.
128672262 if (x < 0 || y < 0) return false;
6867
2/2
✓ Branch 0 taken 322238 times.
✓ Branch 1 taken 127995936 times.
128318174 if (x >= max_x) return false;
6868
3/4
✓ Branch 0 taken 539938 times.
✓ Branch 1 taken 127455998 times.
✓ Branch 2 taken 539938 times.
✗ Branch 3 not taken.
127995936 if (x >= max_x - 8 && cnt == 2) return false;
6869
2/2
✓ Branch 0 taken 127446732 times.
✓ Branch 1 taken 549204 times.
127995936 if (y >= max_y) return false;
6870
6871
4/4
✓ Branch 0 taken 29467302 times.
✓ Branch 1 taken 97979430 times.
✓ Branch 2 taken 92304628 times.
✓ Branch 3 taken 5674802 times.
127446732 return _walkflag_new(x, y, switchblockstate) || (cnt != 1 && _walkflag_new(x + 8, y, switchblockstate));
6872 128672262 }
6873
6874 99195911 static bool effectflag(int32_t x, int32_t y, int32_t layer)
6875 {
6876 99195911 mapscr* s0 = get_scr_for_world_xy(x, y);
6877 99195911 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6878 99195911 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6879
2/2
✓ Branch 0 taken 51566995 times.
✓ Branch 1 taken 47628916 times.
99195911 if (!s1->valid) s1 = s0;
6880
2/2
✓ Branch 0 taken 17705260 times.
✓ Branch 1 taken 81490651 times.
99195911 if (!s2->valid) s2 = s0;
6881
6882 99195911 int pos = COMBOPOS(x % 256, y % 176);
6883 99195911 const newcombo& c = combobuf[s0->data[pos]];
6884 99195911 const newcombo& c1 = combobuf[s1->data[pos]];
6885 99195911 const newcombo& c2 = combobuf[s2->data[pos]];
6886
4/4
✓ Branch 0 taken 98268633 times.
✓ Branch 1 taken 927278 times.
✓ Branch 2 taken 98267267 times.
✓ Branch 3 taken 1366 times.
198391822 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6887
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98267267 times.
✓ Branch 2 taken 926808 times.
✓ Branch 3 taken 1836 times.
99195911 (iswater_type(c2.type))) && DRIEDLAKE);
6888 99195911 int32_t b=1;
6889
2/2
✓ Branch 0 taken 49899696 times.
✓ Branch 1 taken 49296215 times.
99195911 if(x&8) b<<=2;
6890
2/2
✓ Branch 0 taken 41849917 times.
✓ Branch 1 taken 57345994 times.
99195911 if(y&8) b<<=1;
6891
6892 99195911 int32_t cwalkflag = (c.walk>>4);
6893
2/2
✓ Branch 0 taken 76385168 times.
✓ Branch 1 taken 22810743 times.
99195911 if (layer == 0) cwalkflag = (c1.walk>>4);
6894
2/2
✓ Branch 0 taken 76386608 times.
✓ Branch 1 taken 22809303 times.
99195911 if (layer == 1) cwalkflag = (c2.walk>>4);
6895 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6896
4/4
✓ Branch 0 taken 51566995 times.
✓ Branch 1 taken 47628916 times.
✓ Branch 2 taken 22482626 times.
✓ Branch 3 taken 29084369 times.
99195911 if (s1 != s0 && layer < 0)
6897 {
6898
2/2
✓ Branch 0 taken 22469220 times.
✓ Branch 1 taken 13406 times.
22482626 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
6899 22482626 }
6900
4/4
✓ Branch 0 taken 17705260 times.
✓ Branch 1 taken 81490651 times.
✓ Branch 2 taken 13127339 times.
✓ Branch 3 taken 4577921 times.
99195911 if (s2 != s0 && layer < 1)
6901 {
6902
2/2
✓ Branch 0 taken 13119763 times.
✓ Branch 1 taken 7576 times.
13127339 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
6903 13127339 }
6904
6905
2/2
✓ Branch 0 taken 99034941 times.
✓ Branch 1 taken 160970 times.
99195911 return (cwalkflag&b) ? !dried : false;
6906 }
6907
6908 99570795 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
6909 {
6910 DCHECK(cnt == 0 || cnt == 1);
6911 99570795 int max_x = world_w;
6912 99570795 int max_y = world_h;
6913
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 53737072 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
99570795 if (!get_qr(qr_LTTPWALK) && !notLink)
6914 {
6915 45833723 max_x -= 7;
6916 45833723 max_y -= 7;
6917 45833723 }
6918
4/4
✓ Branch 0 taken 99570042 times.
✓ Branch 1 taken 753 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 99569838 times.
99570795 if (x < 0 || y < 0) return false;
6919
2/2
✓ Branch 0 taken 818 times.
✓ Branch 1 taken 99569020 times.
99569838 if (x >= max_x) return false;
6920
3/4
✓ Branch 0 taken 521840 times.
✓ Branch 1 taken 99047180 times.
✓ Branch 2 taken 521840 times.
✗ Branch 3 not taken.
99569020 if (x >= max_x - 8 && cnt == 2) return false;
6921
2/2
✓ Branch 0 taken 373109 times.
✓ Branch 1 taken 99195911 times.
99569020 if (y >= max_y) return false;
6922
6923
3/4
✓ Branch 0 taken 99034151 times.
✓ Branch 1 taken 161760 times.
✓ Branch 2 taken 161760 times.
✗ Branch 3 not taken.
99195911 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
6924 99570795 }
6925
6926 // used by mapdata->isSolid(x,y) in ZScript
6927 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6928 {
6929 int x = zx.getRound(), y = zy.getRound();
6930 {
6931 int max_x = 256;
6932 int max_y = 176;
6933 if (!get_qr(qr_LTTPWALK))
6934 {
6935 max_x -= 7;
6936 max_y -= 7;
6937 }
6938 if (x < 0 || y < 0) return false;
6939 if (x >= max_x) return false;
6940 if (x >= max_x - 8 && cnt == 2) return false;
6941 if (y >= max_y) return false;
6942 }
6943
6944 const mapscr *s1, *s2;
6945
6946 if ( m->layermap[0] > 0 )
6947 {
6948 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
6949 }
6950 else s1 = m;
6951
6952 if ( m->layermap[1] > 0 )
6953 {
6954 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
6955 }
6956 else s2 = m;
6957
6958 zfix unused;
6959 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
6960 }
6961
6962 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
6963 {
6964 DCHECK_LAYER_NEG1_INDEX(layer);
6965 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
6966 if (!m->is_valid()) return false;
6967 return _walkflag_layer(x, y, cnt, m);
6968 }
6969
6970 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
6971 {
6972 int x = zx.getRound(), y = zy.getRound();
6973
6974 if (!get_qr(qr_LTTPWALK))
6975 {
6976 max_x -= 7;
6977 max_y -= 7;
6978 }
6979 if (x < 0 || y < 0) return false;
6980 if (x >= max_x) return false;
6981 if (x >= max_x - 8 && cnt == 2) return false;
6982 if (y >= max_y) return false;
6983
6984 if(!m) return true;
6985
6986 int pos = COMBOPOS(x%256, y%176);
6987 const newcombo* c = &combobuf[m->data[pos]];
6988 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
6989 int32_t b=1;
6990
6991 if(x&8) b<<=2;
6992
6993 if(y&8) b<<=1;
6994
6995 if((c->walk&b) && !dried)
6996 return true;
6997
6998 if(cnt==1) return false;
6999
7000 ++pos;
7001
7002 if(!(x&8))
7003 b<<=2;
7004 else
7005 {
7006 c = &combobuf[m->data[pos]];
7007 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7008 b=1;
7009
7010 if(y&8) b<<=1;
7011 }
7012
7013 return (c->walk&b) ? !dried : false;
7014 }
7015
7016 //Only check the given mapscr*, not its layer 1&2
7017 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7018 {
7019 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7020 }
7021
7022 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7023 {
7024 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7025 }
7026
7027 331739 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7028 {
7029 DCHECK_LAYER_NEG1_INDEX(layer);
7030 331739 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7031
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 329977 times.
331739 if (!m->is_valid()) return false;
7032 329977 return _effectflag_layer(x, y, cnt, m, notLink);
7033 331739 }
7034
7035 393086 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7036 {
7037 393086 int max_x = world_w;
7038 393086 int max_y = world_h;
7039
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 343084 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
393086 if (!get_qr(qr_LTTPWALK) && !notLink)
7040 {
7041 max_x -= 7;
7042 max_y -= 7;
7043 }
7044
2/4
✓ Branch 0 taken 393086 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 393086 times.
393086 if (x < 0 || y < 0) return false;
7045
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 393086 times.
393086 if (x >= max_x) return false;
7046
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 391877 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
393086 if (x >= max_x - 8 && cnt == 2) return false;
7047
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 393086 times.
393086 if (y >= max_y) return false;
7048
7049
1/2
✓ Branch 0 taken 393086 times.
✗ Branch 1 not taken.
393086 if (!m) return true;
7050
7051 393086 int pos = COMBOPOS(x%256, y%176);
7052 393086 const newcombo* c = &combobuf[m->data[pos]];
7053
3/4
✓ Branch 0 taken 392705 times.
✓ Branch 1 taken 381 times.
✓ Branch 2 taken 381 times.
✗ Branch 3 not taken.
393467 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7054 393086 int32_t b=1;
7055
7056
2/2
✓ Branch 0 taken 212080 times.
✓ Branch 1 taken 181006 times.
393086 if(x&8) b<<=2;
7057
7058
2/2
✓ Branch 0 taken 158925 times.
✓ Branch 1 taken 234161 times.
393086 if(y&8) b<<=1;
7059
7060
3/4
✓ Branch 0 taken 324092 times.
✓ Branch 1 taken 68994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 324092 times.
393086 if(((c->walk>>4)&b) && !dried)
7061 324092 return true;
7062
7063
1/2
✓ Branch 0 taken 68994 times.
✗ Branch 1 not taken.
68994 if(cnt==1) return false;
7064
7065 ++pos;
7066
7067 if(!(x&8))
7068 b<<=2;
7069 else
7070 {
7071 c = &combobuf[m->data[pos]];
7072 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7073 b=1;
7074
7075 if(y&8) b<<=1;
7076 }
7077
7078 return ((c->walk>>4)&b) ? !dried : false;
7079 393086 }
7080
7081 812605 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7082 {
7083 812605 int max_x = world_w;
7084 812605 int max_y = world_h;
7085
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 695238 times.
812605 if (!get_qr(qr_LTTPWALK))
7086 {
7087 695238 max_x -= 7;
7088 695238 max_y -= 7;
7089 695238 }
7090
2/4
✓ Branch 0 taken 812605 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 812605 times.
812605 if (x < 0 || y < 0) return false;
7091
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (x >= max_x) return false;
7092
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
812605 if (x >= max_x - 8 && cnt == 2) return false;
7093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (y >= max_y) return false;
7094
7095
3/4
✓ Branch 0 taken 16825 times.
✓ Branch 1 taken 795780 times.
✓ Branch 2 taken 795780 times.
✗ Branch 3 not taken.
812605 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7096 812605 }
7097
7098 812605 bool water_walkflag(int32_t x, int32_t y)
7099 {
7100 812605 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7101 812605 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7102 812605 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7103
7104 812605 int32_t b=1;
7105
2/2
✓ Branch 0 taken 414677 times.
✓ Branch 1 taken 397928 times.
812605 if(x&8) b<<=2;
7106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if(y&8) b<<=1;
7107
7108
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 786228 times.
812605 if(get_qr(qr_NO_SOLID_SWIM))
7109 {
7110
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7111 132 return true;
7112
7113
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7114 292 return true;
7115
7116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7117 return true;
7118 25953 }
7119 else
7120 {
7121
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7122 16371 return true;
7123
7124
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7125 17 return true;
7126
7127
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7128 13 return true;
7129 }
7130
7131 795780 return false;
7132 812605 }
7133
7134 564052 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7135 {
7136
2/2
✓ Branch 0 taken 90935 times.
✓ Branch 1 taken 473117 times.
564052 if(dlevel)
7137
8/8
✓ Branch 0 taken 471712 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 468517 times.
✓ Branch 3 taken 3195 times.
✓ Branch 4 taken 466857 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4199 times.
✓ Branch 7 taken 462658 times.
473117 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7138 10459 return true;
7139
7140
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 553591 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
553593 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7141 return true;
7142
7143
8/8
✓ Branch 0 taken 553324 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 553091 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 552882 times.
✓ Branch 5 taken 209 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 552536 times.
553593 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7144 1057 return true;
7145
7146 // for(int32_t i=0; i<4; i++)
7147
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 551695 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
552536 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7148 36 return true;
7149
7150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552500 times.
552500 if (collide_object(x, y,cnt*8, 1))
7151 return true;
7152
7153 552500 return _walkflag(x,y,cnt);
7154 564052 }
7155
7156 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7157 {
7158 // 16 pixel buffer to account for slopes that are on bordering screens.
7159
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7160 return true;
7161
7162 // for(int32_t i=0; i<4; i++)
7163
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7164 return true;
7165
7166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7167 return true;
7168
7169 12110 return _walkflag(x,y,cnt);
7170 12110 }
7171
7172 37843 void map_bkgsfx(bool on)
7173 {
7174
2/2
✓ Branch 0 taken 37822 times.
✓ Branch 1 taken 21 times.
37843 if(on)
7175 {
7176 37822 cont_sfx(hero_scr->oceansfx);
7177
7178
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 37453 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
37822 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&liBOSS))
7179 315 cont_sfx(hero_scr->bosssfx);
7180 37822 }
7181 else
7182 {
7183 21 adjust_sfx(hero_scr->oceansfx,128,false);
7184 21 adjust_sfx(hero_scr->bosssfx,128,false);
7185
7186
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7187 {
7188
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7189 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7190 114 }
7191 }
7192 37843 }
7193
7194 239 void toggle_switches(dword flags, bool entry)
7195 {
7196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7197
7198 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7199 239 toggle_switches(flags, entry, create_screen_handles(scr));
7200 239 });
7201 239 }
7202 54050 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7203 {
7204
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 53313 times.
54050 if(!flags) return; //No flags to toggle
7205
7206 737 mapscr* m = screen_handles[0].base_scr;
7207 737 int screen = m->screen;
7208 737 bool is_active_screen = is_in_current_region(m);
7209
7210 305041 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7211 304304 byte togglegrid[176] = {0};
7212 304304 mapscr* scr = rpos_handle.scr;
7213 304304 int lyr = rpos_handle.layer;
7214 304304 int pos = rpos_handle.pos;
7215 304304 newcombo const& cmb = combobuf[scr->data[pos]];
7216
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 264880 times.
304304 if(is_active_screen)
7217
2/2
✓ Branch 0 taken 264880 times.
✓ Branch 1 taken 102893 times.
367773 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7218 {
7219 102893 auto& trig = cmb.triggers[idx];
7220
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102893 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102893 if((trig.triggerflags[3] & combotriggerTRIGLEVELSTATE) && trig.trig_lstate < 32)
7221 if(flags&(1<<trig.trig_lstate))
7222 {
7223 auto oldcombo = rpos_handle.data();
7224 do_trigger_combo(rpos_handle, idx, ctrigSWITCHSTATE);
7225 if(rpos_handle.data() != oldcombo) break;
7226 }
7227 367773 }
7228
3/4
✓ Branch 0 taken 303641 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
304304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7229
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 301544 times.
304304 && !(cmb.usrflags & cflag11)) //global state
7230 {
7231
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7232 {
7233 2314 set<int32_t> oldData;
7234 //Increment the combo/cset by the attributes
7235 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7236 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7237
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7238
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7239 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7240
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7241 {
7242 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7243
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7244 {
7245 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7246 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7247 if(oldData.find(cid) != oldData.end())
7248 break;
7249
7250 scr->data[pos] = cid;
7251 if(!(tmp->animflags & AF_CYCLENOCSET))
7252 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7253 oldData.insert(cid);
7254 tmp = &combobuf[cid];
7255 }
7256 238 }
7257 2314 int32_t cmbid = scr->data[pos];
7258
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7259 {
7260 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7261 41 combobuf[cmbid].cur_frame=0;
7262 41 combobuf[cmbid].aclk = 0;
7263
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7264 41 }
7265 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7266
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7268 {
7269
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7270
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7271
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7272
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7273
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7274 return;
7275 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7276
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7277 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7278 return; //This is a switch/block that will be hit later in the loop!
7279 344 set<int32_t> oldData2;
7280 //Increment the combo/cset by the original cmb's attributes
7281
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7282
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7283 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7284
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7285 {
7286 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7287 while(tmp->can_cycle())
7288 {
7289 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7290 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7291 if(oldData2.find(cid) != oldData2.end())
7292 break;
7293
7294 scr_2->data[pos] = cid;
7295 if(!(tmp->animflags & AF_CYCLENOCSET))
7296 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7297 oldData2.insert(cid);
7298 tmp = &combobuf[cid];
7299 }
7300 }
7301 344 int32_t cmbid2 = scr_2->data[pos];
7302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7303 {
7304 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7305 combobuf[cmbid2].cur_frame=0;
7306 combobuf[cmbid2].aclk = 0;
7307 combo_caches::drawing.refresh(cmbid2);
7308 }
7309 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7310 344 }
7311
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7312 446 }
7313 304304 });
7314
7315
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7316 {
7317 newcombo const& cmb = combobuf[mblock2.bcombo];
7318 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7319 {
7320 if(flags&(1<<cmb.attribytes[0]))
7321 {
7322 //Increment the combo/cset by the attributes
7323 int32_t cmbofs = (cmb.attributes[0]/10000L);
7324 int32_t csofs = (cmb.attributes[1]/10000L);
7325 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7326 mblock2.cs = (mblock2.cs + csofs) & 15;
7327 int32_t cmbid = mblock2.bcombo;
7328 if(combobuf[cmbid].animflags & AF_CYCLE)
7329 {
7330 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7331 combobuf[cmbid].cur_frame=0;
7332 combobuf[cmbid].aclk = 0;
7333 combo_caches::drawing.refresh(cmbid);
7334 }
7335 }
7336 }
7337 }
7338
7339
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7340 {
7341 513 int screen_index_offset = get_region_screen_offset(m->screen);
7342 513 word c = m->numFFC();
7343
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7344 {
7345 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7346 334 auto& cmb = ffc_handle.combo();
7347
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 29 times.
363 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7348 {
7349 29 auto& trig = cmb.triggers[idx];
7350
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 if((trig.triggerflags[3] & combotriggerTRIGLEVELSTATE) && trig.trig_lstate < 32)
7351 if(flags&(1<<trig.trig_lstate))
7352 {
7353 auto oldcombo = ffc_handle.data();
7354 do_trigger_combo(ffc_handle, idx, ctrigSWITCHSTATE);
7355 if(ffc_handle.data() != oldcombo) break;
7356 }
7357 29 }
7358 334 }
7359 513 }
7360 54050 }
7361
7362 void toggle_gswitches(int32_t state, bool entry)
7363 {
7364 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7365 toggle_gswitches(state, entry, create_screen_handles(scr));
7366 });
7367 }
7368 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7369 {
7370 bool states[256] = {false};
7371 states[state] = true;
7372 toggle_gswitches(states, entry, screen_handles);
7373 }
7374 15221563 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7375 {
7376
1/2
✓ Branch 0 taken 15221563 times.
✗ Branch 1 not taken.
15221563 if(!states) return;
7377
7378 15221563 auto& combo_cache = combo_caches::gswitch;
7379 15221563 mapscr* base_scr = screen_handles[0].base_scr;
7380 15221563 int screen = base_scr->screen;
7381 15221563 bool is_active_screen = is_in_current_region(base_scr);
7382 15221563 byte togglegrid[176] = {0};
7383
2/2
✓ Branch 0 taken 15221563 times.
✓ Branch 1 taken 106550941 times.
121772504 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7384 {
7385 106550941 mapscr* scr = screen_handles[lyr].scr;
7386
2/2
✓ Branch 0 taken 74215765 times.
✓ Branch 1 taken 32335176 times.
106550941 if (!scr)
7387 74215765 continue;
7388
7389
2/2
✓ Branch 0 taken 5690990976 times.
✓ Branch 1 taken 32335176 times.
5723326152 for(int32_t pos = 0; pos < 176; ++pos)
7390 {
7391 5690990976 int cid = scr->data[pos];
7392 5690990976 auto& mini_cmb = combo_cache.minis[cid];
7393
7394
2/2
✓ Branch 0 taken 93475360 times.
✓ Branch 1 taken 5597515616 times.
5690990976 if (is_active_screen)
7395 {
7396
2/2
✓ Branch 0 taken 5597513734 times.
✓ Branch 1 taken 1882 times.
5597515616 if (mini_cmb.trigger_global_state)
7397 {
7398 1882 auto& cmb = combobuf[cid];
7399
2/2
✓ Branch 0 taken 1882 times.
✓ Branch 1 taken 1882 times.
3764 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7400 {
7401 1882 auto& trig = cmb.triggers[idx];
7402
2/4
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1882 times.
✗ Branch 3 not taken.
1882 if ((trig.triggerflags[3] & combotriggerTRIGGLOBALSTATE) && states[trig.trig_gstate])
7403 {
7404 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7405 do_trigger_combo(rpos_handle, idx, ctrigSWITCHSTATE);
7406 if(rpos_handle.data() != cid) break;
7407 }
7408 1882 }
7409 1882 }
7410 5597515616 }
7411
7412
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5690950581 times.
5690990976 if (!mini_cmb.has_global_state)
7413 5690950581 continue;
7414
7415 40395 newcombo const& cmb = combobuf[cid];
7416
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7417 {
7418 if(states[cmb.attribytes[0]])
7419 {
7420 set<int32_t> oldData;
7421 //Increment the combo/cset by the attributes
7422 int32_t cmbofs = (cmb.attributes[0]/10000L);
7423 int32_t csofs = (cmb.attributes[1]/10000L);
7424 oldData.insert(scr->data[pos]);
7425 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7426 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7427 if(entry && (cmb.usrflags&cflag8))
7428 {
7429 newcombo const* tmp = &combobuf[scr->data[pos]];
7430 while(tmp->can_cycle())
7431 {
7432 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7433 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7434 if(oldData.find(cid) != oldData.end())
7435 break;
7436 scr->data[pos] = cid;
7437 if(!(tmp->animflags & AF_CYCLENOCSET))
7438 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7439 oldData.insert(cid);
7440 tmp = &combobuf[cid];
7441 }
7442 }
7443 int32_t cmbid = scr->data[pos];
7444 if(combobuf[cmbid].animflags & AF_CYCLE)
7445 {
7446 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7447 combobuf[cmbid].cur_frame=0;
7448 combobuf[cmbid].aclk = 0;
7449 combo_caches::drawing.refresh(cmbid);
7450 }
7451 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7452 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7453 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7454 {
7455 if(lyr==lyr2) continue;
7456 if(!(cmb.usrflags&(1<<lyr2))) continue;
7457 if(togglegrid[pos]&(1<<lyr2)) continue;
7458 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7459 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7460 continue;
7461 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7462 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7463 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7464 continue; //This is a switch/block that will be hit later in the loop!
7465 set<int32_t> oldData2;
7466 //Increment the combo/cset by the original cmb's attributes
7467 oldData2.insert(scr_2->data[pos]);
7468 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7469 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7470 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7471 {
7472 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7473 while(tmp->can_cycle())
7474 {
7475 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7476 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7477 if(oldData2.find(cid) != oldData2.end())
7478 break;
7479 scr_2->data[pos] = cid;
7480 if(!(tmp->animflags & AF_CYCLENOCSET))
7481 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7482 oldData2.insert(cid);
7483 tmp = &combobuf[cid];
7484 }
7485 }
7486 int32_t cmbid2 = scr_2->data[pos];
7487 if(combobuf[cmbid2].animflags & AF_CYCLE)
7488 {
7489 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7490 combobuf[cmbid2].cur_frame=0;
7491 combobuf[cmbid2].aclk = 0;
7492 combo_caches::drawing.refresh(cmbid2);
7493 }
7494 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7495 }
7496 }
7497 }
7498 40395 }
7499 32335176 }
7500
7501
4/4
✓ Branch 0 taken 552270 times.
✓ Branch 1 taken 14669293 times.
✓ Branch 2 taken 4744 times.
✓ Branch 3 taken 547526 times.
15221563 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7502 {
7503 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7504
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7505 {
7506 if(states[cmb.attribytes[0]])
7507 {
7508 //Increment the combo/cset by the attributes
7509 int32_t cmbofs = (cmb.attributes[0]/10000L);
7510 int32_t csofs = (cmb.attributes[1]/10000L);
7511 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7512 mblock2.cs = (mblock2.cs + csofs) & 15;
7513 int32_t cmbid = mblock2.bcombo;
7514 if(combobuf[cmbid].animflags & AF_CYCLE)
7515 {
7516 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7517 combobuf[cmbid].cur_frame=0;
7518 combobuf[cmbid].aclk = 0;
7519 combo_caches::drawing.refresh(cmbid);
7520 }
7521 }
7522 }
7523 4744 }
7524
7525
2/2
✓ Branch 0 taken 413479 times.
✓ Branch 1 taken 14808084 times.
15221563 if(is_active_screen)
7526 {
7527 14808084 int screen_index_offset = get_region_screen_offset(screen);
7528 14808084 word c = base_scr->numFFC();
7529
2/2
✓ Branch 0 taken 441793266 times.
✓ Branch 1 taken 14808084 times.
456601350 for (int q = 0; q < c; ++q)
7530 {
7531 441793266 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7532 441793266 int cid = ffc_handle.data();
7533 // auto& mini_cmb = combo_cache.minis[cid];
7534 // if (mini_cmb.trigger_global_state)
7535 441793266 auto& cmb = combobuf[cid];
7536
2/2
✓ Branch 0 taken 441793266 times.
✓ Branch 1 taken 228788 times.
442022054 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7537 {
7538 228788 auto& trig = cmb.triggers[idx];
7539
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 if (states[trig.trig_gstate])
7540 do_trigger_combo(ffc_handle, idx, ctrigSWITCHSTATE);
7541
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 if(ffc_handle.data() != cid) break;
7542 228788 }
7543 441793266 }
7544 14808084 }
7545 15221563 }
7546 53811 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7547 {
7548 bool states[256];
7549
2/2
✓ Branch 0 taken 13775616 times.
✓ Branch 1 taken 53811 times.
13829427 for(auto q = 0; q < 256; ++q)
7550 {
7551 13775616 states[q] = game->gswitch_timers[q] != 0;
7552 13775616 }
7553 53811 toggle_gswitches(states, true, screen_handles);
7554 53811 }
7555 14778384 void run_gswitch_timers()
7556 {
7557 14778384 bool states[256] = {false};
7558 14778384 auto& m = game->gswitch_timers.mut_inner();
7559
2/2
✓ Branch 0 taken 3779224064 times.
✓ Branch 1 taken 14778384 times.
3794002448 for(auto it = m.begin(); it != m.end();)
7560 {
7561
1/2
✓ Branch 0 taken 3779224064 times.
✗ Branch 1 not taken.
3779224064 if(it->second > 0)
7562 if(!--it->second)
7563 {
7564 states[it->first] = true;
7565 it = m.erase(it);
7566 continue;
7567 }
7568 3779224064 ++it;
7569 }
7570 29946136 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7571 15167752 toggle_gswitches(states, false, create_screen_handles(scr));
7572 15167752 });
7573 14778384 }
7574 1116 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7575 {
7576
2/2
✓ Branch 0 taken 285696 times.
✓ Branch 1 taken 1116 times.
286812 for(auto q = 0; q < 256; ++q)
7577 {
7578
1/2
✓ Branch 0 taken 285696 times.
✗ Branch 1 not taken.
285696 if(game->gswitch_timers[q] > 0)
7579 game->gswitch_timers[q] = 0;
7580 285696 }
7581 1116 }
7582
7583 /**** View Map ****/
7584
7585 int32_t mapres = 0;
7586 int32_t view_map_show_mode = 3;
7587
7588 124544 bool displayOnMap(int32_t x, int32_t y)
7589 {
7590 124544 int32_t s = (y<<4) + x;
7591 124544 int mi = mapind(cur_map, s);
7592
2/2
✓ Branch 0 taken 67891 times.
✓ Branch 1 taken 56653 times.
124544 if (!(game->maps[mi]&mVISITED))
7593 67891 return false;
7594
7595 // Don't display if not part of DMap
7596
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 41025 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65619 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7597
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7598
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7599
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7600 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7601 10973 return false;
7602 else
7603 45680 return true;
7604 124544 }
7605
7606 973 void ViewMap()
7607 {
7608 973 ViewingMap = true;
7609
7610 973 BITMAP* mappic = NULL;
7611 static double scales[17] =
7612 {
7613 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7614 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7615 };
7616
7617 973 int32_t px = ((8-(cur_screen&15)) << 9) - 256;
7618 973 int32_t py = ((4-(cur_screen>>4)) * 352) - 176;
7619 973 int32_t lx = ((cur_screen&15)<<8) + HeroX()+8;
7620 973 int32_t ly = ((cur_screen>>4)*176) + HeroY()+8;
7621 973 int32_t sc = 6;
7622
7623 973 bool done=false, redraw=true;
7624
7625 973 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7626
7627
1/2
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
973 if(!mappic)
7628 {
7629 enter_sys_pal();
7630 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7631 exit_sys_pal();
7632 return;
7633 }
7634
7635 973 clear_to_color(mappic, WHITE);
7636
7637 973 auto prev_viewport = viewport;
7638 973 viewport.x = 0;
7639 973 viewport.y = 0;
7640
7641 // draw the map
7642 973 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7643 973 combotile_add_x = 256;
7644 973 combotile_add_y = 0;
7645
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 973 times.
8757 for(int32_t y=0; y<8; y++)
7646 {
7647
2/2
✓ Branch 0 taken 124544 times.
✓ Branch 1 taken 7784 times.
132328 for(int32_t x=0; x<16; x++)
7648 {
7649
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 78864 times.
124544 if (!displayOnMap(x, y))
7650 78864 continue;
7651
7652 45680 int screen = map_scr_xy_to_index(x, y);
7653 45680 auto scrs = loadscr2(screen);
7654 45680 mapscr* scr = &scrs[0];
7655
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!scr->is_valid())
7656 continue;
7657
7658 screen_handles_t screen_handles;
7659
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i <= 6; i++)
7660
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7661
7662 45680 int xx = 0;
7663 45680 int yy = -playing_field_offset;
7664
7665
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45660 times.
45680 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7666 {
7667
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7668
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7669 20 }
7670
7671
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 45505 times.
45680 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7672 {
7673
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7674
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7675 175 }
7676
7677
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7678
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7679
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7680
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7681
7682
2/2
✓ Branch 0 taken 45660 times.
✓ Branch 1 taken 20 times.
45680 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7683 {
7684
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7685
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7686 45660 }
7687
7688
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 putscrdoors(scr, screen_bmp, xx, yy);
7689
2/2
✓ Branch 0 taken 41678 times.
✓ Branch 1 taken 4002 times.
45680 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7690 {
7691
1/2
✓ Branch 0 taken 41678 times.
✗ Branch 1 not taken.
41678 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7692
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39896 times.
41678 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7693 {
7694
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7695
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7696 1782 }
7697 41678 }
7698
7699
2/2
✓ Branch 0 taken 45505 times.
✓ Branch 1 taken 175 times.
45680 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7700 {
7701
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7702
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7703 45505 }
7704
7705
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7706
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7707
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7708
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39896 times.
45680 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7709 {
7710
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7711
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7712 5784 }
7713
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7714
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7715
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(replay_version_check(40))
7716 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7717
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7718
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7719
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7720
7721
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7722
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
45680 }
7723 7784 }
7724
7725 973 viewport = prev_viewport;
7726 973 combotile_add_x = 0;
7727 973 combotile_add_y = 0;
7728
7729 973 destroy_bitmap(screen_bmp);
7730 973 clear_keybuf();
7731 973 pause_all_sfx();
7732
7733 // view it
7734 973 int32_t delay = 0;
7735
7736 973 do
7737 {
7738
2/2
✓ Branch 0 taken 178717 times.
✓ Branch 1 taken 29891 times.
208608 if (replay_version_check(0, 11))
7739 29891 load_control_state();
7740
7741 208608 int32_t step = int32_t(16.0/scales[sc]);
7742 208608 step = (step>>1) + (step&1);
7743 208608 bool r = cRbtn();
7744
7745
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(cLbtn())
7746 {
7747 step <<= 2;
7748 delay = 0;
7749 }
7750
7751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 208608 times.
208608 if(r)
7752 {
7753 if(rUp())
7754 {
7755 py+=step;
7756 redraw=true;
7757 }
7758
7759 if(rDown())
7760 {
7761 py-=step;
7762 redraw=true;
7763 }
7764
7765 if(rLeft())
7766 {
7767 px+=step;
7768 redraw=true;
7769 }
7770
7771 if(rRight())
7772 {
7773 px-=step;
7774 redraw=true;
7775 }
7776 }
7777 else
7778 {
7779
2/2
✓ Branch 0 taken 193729 times.
✓ Branch 1 taken 14879 times.
208608 if(Up())
7780 {
7781 14879 py+=step;
7782 14879 redraw=true;
7783 14879 }
7784
7785
2/2
✓ Branch 0 taken 193574 times.
✓ Branch 1 taken 15034 times.
208608 if(Down())
7786 {
7787 15034 py-=step;
7788 15034 redraw=true;
7789 15034 }
7790
7791
2/2
✓ Branch 0 taken 182159 times.
✓ Branch 1 taken 26449 times.
208608 if(Left())
7792 {
7793 26449 px+=step;
7794 26449 redraw=true;
7795 26449 }
7796
7797
2/2
✓ Branch 0 taken 182774 times.
✓ Branch 1 taken 25834 times.
208608 if(Right())
7798 {
7799 25834 px-=step;
7800 25834 redraw=true;
7801 25834 }
7802 }
7803
7804
2/2
✓ Branch 0 taken 187444 times.
✓ Branch 1 taken 21164 times.
208608 if(delay)
7805 21164 --delay;
7806 else
7807 {
7808 187444 bool a = cAbtn();
7809 187444 bool b = cBbtn();
7810
7811
3/4
✓ Branch 0 taken 1721 times.
✓ Branch 1 taken 185723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1721 times.
187444 if(a && !b)
7812 {
7813
1/2
✓ Branch 0 taken 1721 times.
✗ Branch 1 not taken.
1721 sc=zc_min(sc+1,16);
7814 1721 delay=8;
7815 1721 redraw=true;
7816 1721 }
7817
7818
3/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 186517 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 927 times.
187444 if(b && !a)
7819 {
7820
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1 times.
927 sc=zc_max(sc-1,0);
7821 927 delay=8;
7822 927 redraw=true;
7823 927 }
7824 }
7825
7826
2/2
✓ Branch 0 taken 208597 times.
✓ Branch 1 taken 11 times.
208608 if(rPbtn())
7827 11 --view_map_show_mode;
7828
7829 208608 px = vbound(px,-4096,4096);
7830 208608 py = vbound(py,-1408,1408);
7831
7832 208608 double scale = scales[sc];
7833
7834
2/2
✓ Branch 0 taken 72838 times.
✓ Branch 1 taken 135770 times.
208608 if(!redraw)
7835 {
7836 135770 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
7837 135770 }
7838 else
7839 {
7840 72838 clear_to_color(framebuf,BLACK);
7841 145676 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
7842 72838 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
7843 72838 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
7844
7845 72838 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
7846 72838 redraw=false;
7847 }
7848
7849 208608 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
7850 208608 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
7851
7852
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 201142 times.
208608 if(view_map_show_mode&1)
7853 {
7854 201142 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
7855 201142 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
7856 201142 }
7857
7858
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 203008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
208608 if(view_map_show_mode&2 || r)
7859 203008 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
7860
7861
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(r)
7862 {
7863 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
7864 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
7865 }
7866
7867 208608 advanceframe(false, false);
7868
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 178717 times.
208608 if (replay_version_check(11))
7869 178717 load_control_state();
7870
7871
2/2
✓ Branch 0 taken 207636 times.
✓ Branch 1 taken 972 times.
208608 if(getInput(btnS, true, false, true)) //rSbtn
7872 972 done = true;
7873
7874
2/2
✓ Branch 0 taken 973 times.
✓ Branch 1 taken 207635 times.
417216 }
7875
2/2
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 207636 times.
208608 while(!done && !Quit);
7876
7877 973 ViewingMap = false;
7878 973 destroy_bitmap(mappic);
7879 973 resume_all_sfx();
7880 973 }
7881
7882 1075 int32_t onViewMap()
7883 {
7884
4/6
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 973 times.
1075 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
7885 {
7886 973 clear_to_color(framebuf,BLACK);
7887 973 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
7888 973 advanceframe(true);
7889 973 ViewMap();
7890 973 }
7891
7892 1075 return D_O_K;
7893 }
7894
7895 35784331 bool isGrassType(int32_t type)
7896 {
7897
2/2
✓ Branch 0 taken 35107919 times.
✓ Branch 1 taken 676412 times.
35784331 switch(type)
7898 {
7899 case cTALLGRASS:
7900 case cTALLGRASSNEXT:
7901 case cTALLGRASSTOUCHY:
7902 676412 return true;
7903 }
7904
7905 35107919 return false;
7906 35784331 }
7907
7908 20914 bool isFlowersType(int32_t type)
7909 {
7910
2/2
✓ Branch 0 taken 16574 times.
✓ Branch 1 taken 4340 times.
20914 switch(type)
7911 {
7912 case cFLOWERS:
7913 case cFLOWERSTOUCHY:
7914 4340 return true;
7915 }
7916
7917 16574 return false;
7918 20914 }
7919
7920 bool isGenericType(int32_t type)
7921 {
7922 switch(type)
7923 {
7924 case cTRIGGERGENERIC:
7925 return true;
7926 }
7927
7928 return false;
7929 }
7930
7931 26056 bool isBushType(int32_t type)
7932 {
7933
2/2
✓ Branch 0 taken 20914 times.
✓ Branch 1 taken 5142 times.
26056 switch(type)
7934 {
7935 case cBUSH:
7936 case cBUSHNEXT:
7937 case cBUSHTOUCHY:
7938 case cBUSHNEXTTOUCHY:
7939
7940 5142 return true;
7941 }
7942
7943 20914 return false;
7944 26056 }
7945
7946 bool isSlashType(int32_t type)
7947 {
7948 switch(type)
7949 {
7950 case cSLASH:
7951 case cSLASHITEM:
7952 case cSLASHTOUCHY:
7953 case cSLASHITEMTOUCHY:
7954 case cSLASHNEXT:
7955 case cSLASHNEXTITEM:
7956 case cSLASHNEXTTOUCHY:
7957 case cSLASHNEXTITEMTOUCHY:
7958 return true;
7959 }
7960
7961 return false;
7962 }
7963
7964 15695 bool isCuttableNextType(int32_t type)
7965 {
7966
2/2
✓ Branch 0 taken 9788 times.
✓ Branch 1 taken 5907 times.
15695 switch(type)
7967 {
7968 case cSLASHNEXT:
7969 case cSLASHNEXTITEM:
7970 case cTALLGRASSNEXT:
7971 case cBUSHNEXT:
7972 case cSLASHNEXTTOUCHY:
7973 case cSLASHNEXTITEMTOUCHY:
7974 case cBUSHNEXTTOUCHY:
7975 5907 return true;
7976 }
7977
7978 9788 return false;
7979 15695 }
7980
7981 17546 bool isTouchyType(int32_t type)
7982 {
7983
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11496 times.
17546 switch(type)
7984 {
7985 case cSLASHTOUCHY:
7986 case cSLASHITEMTOUCHY:
7987 case cBUSHTOUCHY:
7988 case cFLOWERSTOUCHY:
7989 case cTALLGRASSTOUCHY:
7990 case cSLASHNEXTTOUCHY:
7991 case cSLASHNEXTITEMTOUCHY:
7992 case cBUSHNEXTTOUCHY:
7993 11496 return true;
7994 }
7995
7996 6050 return false;
7997 17546 }
7998
7999 29333190 bool isCuttableType(int32_t type)
8000 {
8001
2/2
✓ Branch 0 taken 28883925 times.
✓ Branch 1 taken 449265 times.
29333190 switch(type)
8002 {
8003 case cSLASH:
8004 case cSLASHITEM:
8005 case cBUSH:
8006 case cFLOWERS:
8007 case cTALLGRASS:
8008 case cTALLGRASSNEXT:
8009 case cSLASHNEXT:
8010 case cSLASHNEXTITEM:
8011 case cBUSHNEXT:
8012
8013 case cSLASHTOUCHY:
8014 case cSLASHITEMTOUCHY:
8015 case cBUSHTOUCHY:
8016 case cFLOWERSTOUCHY:
8017 case cTALLGRASSTOUCHY:
8018 case cSLASHNEXTTOUCHY:
8019 case cSLASHNEXTITEMTOUCHY:
8020 case cBUSHNEXTTOUCHY:
8021 449265 return true;
8022 }
8023
8024 28883925 return false;
8025 29333190 }
8026
8027 17322 bool isCuttableItemType(int32_t type)
8028 {
8029
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16898 times.
17322 switch(type)
8030 {
8031 case cSLASHITEM:
8032 case cBUSH:
8033 case cFLOWERS:
8034 case cTALLGRASS:
8035 case cTALLGRASSNEXT:
8036 case cSLASHNEXTITEM:
8037 case cBUSHNEXT:
8038
8039 case cSLASHITEMTOUCHY:
8040 case cBUSHTOUCHY:
8041 case cFLOWERSTOUCHY:
8042 case cTALLGRASSTOUCHY:
8043 case cSLASHNEXTITEMTOUCHY:
8044 case cBUSHNEXTTOUCHY:
8045 16898 return true;
8046 }
8047
8048 424 return false;
8049 17322 }
8050
8051 66 bool is_push(mapscr* m, int32_t pos)
8052 {
8053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
8054 return true;
8055 66 newcombo const& cmb = combobuf[m->data[pos]];
8056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
8057 return true;
8058
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
8059 14 return true;
8060
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8061 return true; //Counts as 'pushblock' flag
8062 52 return false;
8063 66 }
8064
8065 410 static std::map<int, screen_state_t> screen_states;
8066
8067 35860 std::map<int, screen_state_t>& get_screen_states()
8068 {
8069 35860 return screen_states;
8070 }
8071
8072 44197725 screen_state_t& get_screen_state(int screen)
8073 {
8074 44197725 return screen_states[screen];
8075 }
8076
8077 575 void clear_screen_states()
8078 {
8079 575 screen_states.clear();
8080 575 }
8081
8082 1439 void screen_item_set_state(int screen, ScreenItemState state)
8083 {
8084 1439 get_screen_state(screen).item_state = state;
8085 1439 }
8086
8087 37019 void mark_visited(int screen)
8088 {
8089
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 36544 times.
37019 if (screen < 0x80)
8090 {
8091
2/2
✓ Branch 0 taken 24624 times.
✓ Branch 1 taken 11920 times.
36544 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8092 11920 game->maps[mapind(cur_map, screen)] |= mVISITED;
8093
8094 36544 markBmap(-1, screen);
8095 36544 }
8096 37019 }
8097